DBMS_SQL包提供查詢PolarDB PostgreSQL版(相容Oracle)動態SQL的功能,可以在應用運行時構建查詢。
PolarDB PostgreSQL版(相容Oracle)支援查詢動態SQL,且以與Oracle相容的方式來使用動態SQL。
函數/預存程序 | 類型 | 傳回型別 | 說明 |
BIND_VARIABLE(c, name, value [, out_value_size ]) | 預存程序 | N/A | 將值綁定到變數。 |
BIND_VARIABLE_CHAR(c, name, value [, out_value_size ]) | 預存程序 | N/A | 將CHAR值綁定到變數。 |
BIND_VARIABLE_RAW(c, name, value [, out_value_size ]) | 預存程序 | N/A | 將RAW值綁定到變數。 |
CLOSE_CURSOR(c IN OUT) | 預存程序 | N/A | 關閉遊標。 |
COLUMN_VALUE(c, position, value OUT [, column_error OUT [, actual_length OUT ]]) | 預存程序 | N/A | 將列值返回到變數中。 |
COLUMN_VALUE_CHAR(c, position, value OUT [, column_error OUT [, actual_length OUT ]]) | 預存程序 | N/A | 將CHAR列值返回到變數中。 |
COLUMN_VALUE_RAW(c, position, value OUT [, column_error OUT [, actual_length OUT ]]) | 預存程序 | N/A | 將RAW列值返回到變數中。 |
DEFINE_COLUMN(c, position, column [, column_size ]) | 預存程序 | N/A | 在SELECT列表中定義一列。 |
DEFINE_COLUMN_CHAR(c, position, column, column_size) | 預存程序 | N/A | 在SELECT列表中定義CHAR列。 |
DEFINE_COLUMN_RAW(c, position, column, column_size) | 預存程序 | N/A | 在SELECT列表中定義RAW列。 |
DEFINE_ARRAY(c,position,table_variable,cnt, lower_bnd) | 預存程序 | N/A | 將需要擷取行的列定義為數組。 |
DESCRIBE_COLUMNS | 預存程序 | N/A | 定義用於儲存遊標結果集的列。 |
EXECUTE(c) | 函數 | INTEGER | 執行遊標。 |
EXECUTE_AND_FETCH(c [, exact ]) | 函數 | INTEGER | 執行一個遊標並擷取一行。 |
FETCH_ROWS(c) | 函數 | INTEGER | 從遊標中擷取的行數。 |
IS_OPEN(c) | 函數 | BOOLEAN | 查看遊標是否開啟。 |
LAST_ROW_COUNT | 函數 | INTEGER | 返回擷取的累計行數。 |
OPEN_CURSOR | 函數 | INTEGER | 開啟遊標。 |
PARSE(c, statement, language_flag) | 預存程序 | N/A | 解析語句。 |
與Oracle版本的DBMS_SQL執行相比,PolarDB的DBMS_SQL執行是部分執行。PolarDB僅支援上述表中列出的函數和預存程序。
下表中列出了DBM_SQL包允許使用的公開變數。
公開變數 | 資料類型 | 取值 | 說明 |
native | INTEGER | 1 | 與Oracle文法相容。更多資訊請參見DBMS_SQL.PARSE。 |
V6 | INTEGER | 2 | 與Oracle文法相容。更多資訊請參見DBMS_SQL.PARSE。 |
V7 | INTEGER | 3 | 與Oracle文法相容。更多資訊請參見DBMS_SQL.PARSE。 |
BIND_VARIABLE
預存程序BIND_VARIABLE
用於將一個值和SQL命令中的IN或IN OUT綁定變數相關聯。
BIND_VARIABLE(c INTEGER, name VARCHAR2,
value { BLOB | CLOB | DATE | FLOAT | INTEGER | NUMBER |
TIMESTAMP | VARCHAR2 }
[, out_value_size INTEGER ])
參數
參數名稱 | 描述 |
c | 與帶有綁定變數SQL命令相對應遊標的ID。 |
name | SQL命令中綁定變數的名稱。 |
value | 被分配的值。 |
out_value_size | 如果name 是一個IN OUT模式的變數,則定義輸出值的最大長度。如果沒有指定這個參數,則將當前value的長度預設為最大值長度。 |
樣本
下面的匿名代碼塊使用綁定變數向表emp
中插入一條記錄。
DECLARE
curid INTEGER;
v_sql VARCHAR2(150) := 'INSERT INTO emp VALUES ' ||
'(:p_empno, :p_ename, :p_job, :p_mgr, ' ||
':p_hiredate, :p_sal, :p_comm, :p_deptno)';
v_empno emp.empno%TYPE;
v_ename emp.ename%TYPE;
v_job emp.job%TYPE;
v_mgr emp.mgr%TYPE;
v_hiredate emp.hiredate%TYPE;
v_sal emp.sal%TYPE;
v_comm emp.comm%TYPE;
v_deptno emp.deptno%TYPE;
v_status INTEGER;
BEGIN
curid := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(curid,v_sql,DBMS_SQL.native);
v_empno := 9001;
v_ename := 'JONES';
v_job := 'SALESMAN';
v_mgr := 7369;
v_hiredate := TO_DATE('13-DEC-07','DD-MON-YY');
v_sal := 8500.00;
v_comm := 1500.00;
v_deptno := 40;
DBMS_SQL.BIND_VARIABLE(curid,':p_empno',v_empno);
DBMS_SQL.BIND_VARIABLE(curid,':p_ename',v_ename);
DBMS_SQL.BIND_VARIABLE(curid,':p_job',v_job);
DBMS_SQL.BIND_VARIABLE(curid,':p_mgr',v_mgr);
DBMS_SQL.BIND_VARIABLE(curid,':p_hiredate',v_hiredate);
DBMS_SQL.BIND_VARIABLE(curid,':p_sal',v_sal);
DBMS_SQL.BIND_VARIABLE(curid,':p_comm',v_comm);
DBMS_SQL.BIND_VARIABLE(curid,':p_deptno',v_deptno);
v_status := DBMS_SQL.EXECUTE(curid);
DBMS_OUTPUT.PUT_LINE('Number of rows processed: ' || v_status);
DBMS_SQL.CLOSE_CURSOR(curid);
END;
顯示結果如下:Number of rows processed: 1
BIND_VARIABLE_CHAR
預存程序BIND_VARIABLE_CHAR
將一個CHAR類型的值和SQL命令中的IN或IN OUT綁定變數相關聯。
BIND_VARIABLE_CHAR(c INTEGER, name VARCHAR2, value CHAR
[, out_value_size INTEGER ])
參數
參數名稱 | 描述 |
c | 與帶有綁定變數的SQL命令相對應的遊標ID。 |
name | SQL命令中綁定變數的名稱。 |
value | 被分配的類型為RAW的值。 |
out_value_size | 如果name 是一個IN OUT模式的變數,則定義輸出值的最大長度。如果沒有指定這個參數,則將當前值的長度預設為最大值長度。 |
BIND_VARIABLE_RAW
預存程序BIND_VARIABLE_RAW
用於將一個類型為RAW的值和SQL命令中的IN或IN OUT綁定變數相關聯。
BIND_VARIABLE_RAW(c INTEGER, name VARCHAR2, value RAW
[, out_value_size INTEGER ])
參數
參數名稱 | 描述 |
c | 與帶有綁定變數的SQL命令相對應的遊標ID。 |
name | SQL命令中綁定變數的名稱。 |
value | 被分配的類型為RAW的值。 |
out_value_size | 如果name 是一個IN OUT模式的變數,那麼定義輸出值的最大長度。如果沒有指定這個參數,那麼將當前值的長度預設為最大值長度。 |
CLOSE_CURSOR
預存程序CLOSE_CURSOR
關閉一個已開啟的遊標。當關閉遊標後,釋放分配給遊標的資源,並且不能再使用這個遊標。
CLOSE_CURSOR(c IN OUT INTEGER)
參數
參數名稱 | 描述 |
c | 需要關閉遊標的ID。 |
樣本
DECLARE
curid INTEGER;
BEGIN
curid := DBMS_SQL.OPEN_CURSOR;
.
.
.
DBMS_SQL.CLOSE_CURSOR(curid);
END;
COLUMN_VALUE
預存程序COLUMN_VALUE
定義了一個變數,用於從遊標中接收值。
COLUMN_VALUE(c INTEGER, position INTEGER, value OUT { BLOB |
CLOB | DATE | FLOAT | INTEGER | NUMBER | TIMESTAMP | VARCHAR2 }
[, column_error OUT NUMBER [, actual_length OUT INTEGER ]])
參數
參數名稱 | 描述 |
c | 一個遊標的ID,用於將資料返回給被定義變數。 |
position | 在遊標中返回資料的位置。在遊標中的第一個位置值是1。 |
value | 通過前面的FETCH操作在遊標中接收返回資料的變數。 |
column_error | 如果發生異常錯誤,這個參數表示與列相關的錯誤碼。 |
actual_length | 在進行截斷操作前,資料的實際長度。 |
樣本
下面的代碼顯示一個匿名代碼塊的一部分。這部分代碼的功能是通過預存程序COLUMN_VALUE
,從遊標中接收資料。
DECLARE
curid INTEGER;
v_empno NUMBER(4);
v_ename VARCHAR2(10);
v_hiredate DATE;
v_sal NUMBER(7,2);
v_comm NUMBER(7,2);
v_sql VARCHAR2(50) := 'SELECT empno, ename, hiredate, sal, ' ||
'comm FROM emp';
v_status INTEGER;
BEGIN
.
.
.
LOOP
v_status := DBMS_SQL.FETCH_ROWS(curid);
EXIT WHEN v_status = 0;
DBMS_SQL.COLUMN_VALUE(curid,1,v_empno);
DBMS_SQL.COLUMN_VALUE(curid,2,v_ename);
DBMS_SQL.COLUMN_VALUE(curid,3,v_hiredate);
DBMS_SQL.COLUMN_VALUE(curid,4,v_sal);
DBMS_SQL.COLUMN_VALUE(curid,4,v_sal);
DBMS_SQL.COLUMN_VALUE(curid,5,v_comm);
DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || RPAD(v_ename,10) || ' ' ||
TO_CHAR(v_hiredate,'yyyy-mm-dd') || ' ' ||
TO_CHAR(v_sal,'9,999.99') || ' ' ||
TO_CHAR(NVL(v_comm,0),'9,999.99'));
END LOOP;
DBMS_SQL.CLOSE_CURSOR(curid);
END;
COLUMN_VALUE_CHAR
預存程序COLUMN_VALUE_CHAR
定義一個變數,用於從遊標中接收一個CHAR類型的值。
COLUMN_VALUE_CHAR(c INTEGER, position INTEGER, value OUT CHAR
[, column_error OUT NUMBER [, actual_length OUT INTEGER ]])
參數
參數名稱 | 描述 |
c | 遊標的ID,用於向被定義的變數返回資料。 |
position | 返回資料在遊標內部的位置。在遊標中的第一個位置是1。 |
value | 類型為CHAR的變數,通過前面已經進行FETCH操作,從遊標中接收資料。 |
column_error | 如果有任何錯誤發生,這個參數表示與列相關的錯誤碼。 |
actual_length | 在任何截斷的操作前,資料的實際長度。 |
COLUMN_VALUE_RAW
預存程序COLUMN_VALUE_RAW
定義一個變數,用於從遊標中接收一個RAW型的值。
COLUMN_VALUE_RAW(c INTEGER, position INTEGER, value OUT RAW
[, column_error OUT NUMBER [, actual_length OUT INTEGER ]])
參數
參數名稱 | 描述 |
c | 遊標的ID,用於向被定義變數返回資料。 |
position | 返回資料在遊標中位置。在遊標中的第一個值是1。 |
value | 類型為RAW的變數,通過前面已經進行FETCH操作,從遊標中接收資料。 |
column_error | 如果有任何錯誤發生,這個參數表示與列相關的錯誤碼。 |
actual_length | 在任何截斷的操作前,資料的實際長度。 |
DEFINE_COLUMN
預存程序DEFINE_COLUMN
在SELECT列表中定義了一個列或者運算式,這個列或者運算式將在遊標中返回和取出。
DEFINE_COLUMN(c INTEGER, position INTEGER, column { BLOB |
CLOB | DATE | FLOAT | INTEGER | NUMBER | TIMESTAMP | VARCHAR2 }
[, column_size INTEGER ])
參數
參數名稱 | 描述 |
c | 與SELECT命令相關聯的遊標ID。 |
position | 被定義的列或者運算式在SELECT列表中的位置。 |
column | 在SELECT列表中位置為position的列或者運算式資料類型相等的變數。 |
column_size | 返回資料的最大長度。如果列的資料類型是VARCHAR2, 那麼必須指定column_size。長度超過column_size的返回資料將被截斷為長度是column_size的字串。 |
樣本
下面顯示了如何使用預存程序DEFINE_COLUMN
定義表emp
的列empno
、ename
、hiredate
、sal
和comm
。
DECLARE
curid INTEGER;
v_empno NUMBER(4);
v_ename VARCHAR2(10);
v_hiredate DATE;
v_sal NUMBER(7,2);
v_comm NUMBER(7,2);
v_sql VARCHAR2(50) := 'SELECT empno, ename, hiredate, sal, ' ||
'comm FROM emp';
v_status INTEGER;
BEGIN
curid := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(curid,v_sql,DBMS_SQL.native);
DBMS_SQL.DEFINE_COLUMN(curid,1,v_empno);
DBMS_SQL.DEFINE_COLUMN(curid,2,v_ename,10);
DBMS_SQL.DEFINE_COLUMN(curid,3,v_hiredate);
DBMS_SQL.DEFINE_COLUMN(curid,4,v_sal);
DBMS_SQL.DEFINE_COLUMN(curid,5,v_comm);
.
.
.
END;
下面顯示了針對上個樣本的另外一種實現方法,產生的結果完全一樣。需要注意的是與資料類型的長度無關。列empno
、sal
和comm
返回的資料長度分別等於NUMBER(4)
和NUMBER(7,2)
,儘管v_num
是被定義為NUMBER(1)
。列ename
將返回的資料長度可達到調用預存程序DEFINE_COLUMN
中定義的長度參數,而不是對於v_varchar
聲明中類型VARCHAR2(1)
。返回資料的實際長度是由預存程序DEFINE_COLUMN
指定。
DECLARE
curid INTEGER;
v_num NUMBER(1);
v_varchar VARCHAR2(1);
v_date DATE;
v_sql VARCHAR2(50) := 'SELECT empno, ename, hiredate, sal, ' ||
'comm FROM emp';
v_status INTEGER;
BEGIN
curid := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(curid,v_sql,DBMS_SQL.native);
DBMS_SQL.DEFINE_COLUMN(curid,1,v_num);
DBMS_SQL.DEFINE_COLUMN(curid,2,v_varchar,10);
DBMS_SQL.DEFINE_COLUMN(curid,3,v_date);
DBMS_SQL.DEFINE_COLUMN(curid,4,v_num);
DBMS_SQL.DEFINE_COLUMN(curid,5,v_num);
.
.
.
END;
DEFINE_COLUMN_CHAR
預存程序DEFINE_COLUMN_CHAR
在SELECT列表中定義了一個CHAR類型的列或運算式,您在遊標中返回並擷取這個CHAR類型的列或運算式。
DEFINE_COLUMN_CHAR(c INTEGER, position INTEGER, column CHAR, column_size INTEGER)
參數
參數名稱 | 描述 |
c | 與SELECT命令相關的遊標ID。 |
position | 被定義的列或者運算式在SELECT列表中的位置。 |
column | 一個CHAR類型變數。 |
column_size | 返回資料的最大長度,長度超過column_size的返回資料將被截斷。 |
DEFINE_COLUMN_RAW
預存程序DEFINE_COLUMN_RAW
在SELECT列表中定義了一個RAW類型的列或運算式,您在遊標中返回並擷取這個RAW類型的列或運算式。
DEFINE_COLUMN_RAW(c INTEGER, position INTEGER, column RAW,
column_size INTEGER)
參數
參數名稱 | 描述 |
c | 與SELECT命令相關的遊標ID。 |
position | 被定義的列或者運算式在SELECT列表中的位置。 |
column | 一個RAW類型變數。 |
column_size | 返回資料的最大長度,當返回資料的長度超過column_size時,將會被截斷。 |
DEFINE_ARRAY
DEFINE_ARRAY
預存程序將需要擷取行的列定義為數組。文法如下:DEFINE_ARRAY (
c IN INTEGER,
position IN INTEGER,
<table_variable> IN <datatype>,
cnt IN INTEGER,
lower_bnd IN INTEGER);
參數名稱 | 描述 |
c | 需要綁定數組的遊標的ID。 |
position | 列在數組中的相對位置。 |
table_variable | 已定義為<datatype>類型的變數。其中,<datatype>類型的取值如下:
|
cnt | 擷取的行的數量。必須為大於0的整數。 |
lower_bnd | 從此下限索引開始將查詢結果複製到數組中。 |
樣本
t
,並從表t
中擷取2行資料。create table t as select i as a,2 * i as b,3 * i as c from generate_series(1,3) i;
DECLARE
c INTEGER;
d NUMBER;
n_tab dbms_sql.varchar2_Table;
n_tab1 dbms_sql.varchar2_Table;
BEGIN
c := dbms_sql.open_cursor;
dbms_sql.parse(c,
'select * from t',
dbms_sql.native);
dbms_sql.define_array(c,1,n_tab,2,1);
d := dbms_sql.execute(c);
d := dbms_sql.fetch_rows(c);
dbms_output.put_line('fetch rows is ' || d);
dbms_sql.column_value(c,
1,
n_tab1);
FOR i IN 1 .. d LOOP
dbms_output.put_line(n_tab1(i));
END LOOP;
dbms_sql.close_cursor(c);
END;
顯示結果如下:fetch rows is 2
1
2
DESCRIBE_COLUMNS
DESCRIBE_COLUMNS
預存程序用於描述遊標返回的列。
DESCRIBE_COLUMNS(c INTEGER, col_cnt OUT INTEGER, desc_t OUT
DESC_TAB);
參數
參數名稱 | 描述 |
c | 遊標的ID 。 |
col_cnt | 遊標結果集中列的數量。 |
desc_tab | 包含遊標所返回的每列的描述的表。描述為DESC_REC類型,包含值請參見下表。 |
列名稱 | 類型 |
col_type | INTEGER |
col_max_len | INTEGER |
col_name | VARCHAR2(128) |
col_name_len | INTEGER |
col_schema_name | VARCHAR2(128) |
col_schema_name_len | INTEGER |
col_precision | INTEGER |
col_scale | INTEGER |
col_charsetid | INTEGER |
col_charsetform | INTEGER |
col_null_ok | BOOLEAN |
EXECUTE
函數EXECUTE
用於執行一個已解析SQL語句或SPL代碼塊。
status INTEGER EXECUTE(c INTEGER)
參數
參數名稱 | 描述 |
c | 需要執行的SQL語句或SPL代碼塊的遊標ID,其中SQL命令已解析。 |
status | 如果SQL命令是DELETE、INSERT或UPDATE,那麼這個參數代表已處理的記錄數。如果是其它命令,那麼這個參數沒有意義。 |
樣本
下面的匿名代碼塊向表dept
中插入了一條記錄。
DECLARE
curid INTEGER;
v_sql VARCHAR2(50);
v_status INTEGER;
BEGIN
curid := DBMS_SQL.OPEN_CURSOR;
v_sql := 'INSERT INTO dept VALUES (50, ''HR'', ''LOS ANGELES'')';
DBMS_SQL.PARSE(curid, v_sql, DBMS_SQL.native);
v_status := DBMS_SQL.EXECUTE(curid);
DBMS_OUTPUT.PUT_LINE('Number of rows processed: ' || v_status);
DBMS_SQL.CLOSE_CURSOR(curid);
END;
EXECUTE_AND_FETCH
函數EXECUTE_AND_FETCH
用於執行一條已解析的SELECT命令,並且取回一條記錄。
status INTEGER EXECUTE_AND_FETCH(c INTEGER
[, exact BOOLEAN ])
參數
參數名稱 | 描述 |
c | 執行SELECT命令對應的遊標ID。 |
exact |
|
status |
|
樣本
以下預存程序使用函數EXECUTE_AND_FETCH
根據僱員的姓名來擷取一條僱員記錄。如果沒有找到相應的僱員記錄,或者找到多個具有相同的姓名的僱員,都會產生異常。
CREATE OR REPLACE PROCEDURE select_by_name(
p_ename emp.ename%TYPE
)
IS
curid INTEGER;
v_empno emp.empno%TYPE;
v_hiredate emp.hiredate%TYPE;
v_sal emp.sal%TYPE;
v_comm emp.comm%TYPE;
v_dname dept.dname%TYPE;
v_disp_date VARCHAR2(10);
v_sql VARCHAR2(120) := 'SELECT empno, hiredate, sal, ' ||
'NVL(comm, 0), dname ' ||
'FROM emp e, dept d ' ||
'WHERE ename = :p_ename ' ||
'AND e.deptno = d.deptno';
v_status INTEGER;
BEGIN
curid := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(curid,v_sql,DBMS_SQL.native);
DBMS_SQL.BIND_VARIABLE(curid,':p_ename',UPPER(p_ename));
DBMS_SQL.DEFINE_COLUMN(curid,1,v_empno);
DBMS_SQL.DEFINE_COLUMN(curid,2,v_hiredate);
DBMS_SQL.DEFINE_COLUMN(curid,3,v_sal);
DBMS_SQL.DEFINE_COLUMN(curid,4,v_comm);
DBMS_SQL.DEFINE_COLUMN(curid,5,v_dname,14);
v_status := DBMS_SQL.EXECUTE_AND_FETCH(curid,TRUE);
DBMS_SQL.COLUMN_VALUE(curid,1,v_empno);
DBMS_SQL.COLUMN_VALUE(curid,2,v_hiredate);
DBMS_SQL.COLUMN_VALUE(curid,3,v_sal);
DBMS_SQL.COLUMN_VALUE(curid,4,v_comm);
DBMS_SQL.COLUMN_VALUE(curid,5,v_dname);
v_disp_date := TO_CHAR(v_hiredate, 'MM/DD/YYYY');
DBMS_OUTPUT.PUT_LINE('Number : ' || v_empno);
DBMS_OUTPUT.PUT_LINE('Name : ' || UPPER(p_ename));
DBMS_OUTPUT.PUT_LINE('Hire Date : ' || v_disp_date);
DBMS_OUTPUT.PUT_LINE('Salary : ' || v_sal);
DBMS_OUTPUT.PUT_LINE('Commission: ' || v_comm);
DBMS_OUTPUT.PUT_LINE('Department: ' || v_dname);
DBMS_SQL.CLOSE_CURSOR(curid);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Employee ' || p_ename || ' not found');
DBMS_SQL.CLOSE_CURSOR(curid);
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('Too many employees named, ' ||
p_ename || ', found');
DBMS_SQL.CLOSE_CURSOR(curid);
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('The following is SQLERRM:');
DBMS_OUTPUT.PUT_LINE(SQLERRM);
DBMS_OUTPUT.PUT_LINE('The following is SQLCODE:');
DBMS_OUTPUT.PUT_LINE(SQLCODE);
DBMS_SQL.CLOSE_CURSOR(curid);
END;
顯示結果如下:EXEC select_by_name('MARTIN')
Number : 7654
Name : MARTIN
Hire Date : 09/28/1981
Salary : 1250
Commission: 1400
Department: SALES
FETCH_ROWS
函數FETCH_ROWS
從一個遊標中擷取的行的數量。
status INTEGER FETCH_ROWS(c INTEGER)
參數
參數名稱 | 描述 |
c | 用於擷取行的遊標ID。 |
status | 如果成功擷取行,返回1。如果沒有擷取到行,返回0。 |
樣本
以下樣本從表emp
中取出記錄,並且顯示結果。
DECLARE
curid INTEGER;
v_empno NUMBER(4);
v_ename VARCHAR2(10);
v_hiredate DATE;
v_sal NUMBER(7,2);
v_comm NUMBER(7,2);
v_sql VARCHAR2(50) := 'SELECT empno, ename, hiredate, sal, ' ||
'comm FROM emp';
v_status INTEGER;
BEGIN
curid := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(curid,v_sql,DBMS_SQL.native);
DBMS_SQL.DEFINE_COLUMN(curid,1,v_empno);
DBMS_SQL.DEFINE_COLUMN(curid,2,v_ename,10);
DBMS_SQL.DEFINE_COLUMN(curid,3,v_hiredate);
DBMS_SQL.DEFINE_COLUMN(curid,4,v_sal);
DBMS_SQL.DEFINE_COLUMN(curid,5,v_comm);
v_status := DBMS_SQL.EXECUTE(curid);
DBMS_OUTPUT.PUT_LINE('EMPNO ENAME HIREDATE SAL COMM');
DBMS_OUTPUT.PUT_LINE('----- ---------- ---------- -------- ' ||
'--------');
LOOP
v_status := DBMS_SQL.FETCH_ROWS(curid);
EXIT WHEN v_status = 0;
DBMS_SQL.COLUMN_VALUE(curid,1,v_empno);
DBMS_SQL.COLUMN_VALUE(curid,2,v_ename);
DBMS_SQL.COLUMN_VALUE(curid,3,v_hiredate);
DBMS_SQL.COLUMN_VALUE(curid,4,v_sal);
DBMS_SQL.COLUMN_VALUE(curid,4,v_sal);
DBMS_SQL.COLUMN_VALUE(curid,5,v_comm);
DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || RPAD(v_ename,10) || ' ' ||
TO_CHAR(v_hiredate,'yyyy-mm-dd') || ' ' ||
TO_CHAR(v_sal,'9,999.99') || ' ' ||
TO_CHAR(NVL(v_comm,0),'9,999.99'));
END LOOP;
DBMS_SQL.CLOSE_CURSOR(curid);
END;
顯示結果如下:EMPNO ENAME HIREDATE SAL COMM
----- ---------- ---------- -------- --------
7369 SMITH 1980-12-17 800.00 .00
7499 ALLEN 1981-02-20 1,600.00 300.00
7521 WARD 1981-02-22 1,250.00 500.00
7566 JONES 1981-04-02 2,975.00 .00
7654 MARTIN 1981-09-28 1,250.00 1,400.00
7698 BLAKE 1981-05-01 2,850.00 .00
7782 CLARK 1981-06-09 2,450.00 .00
7788 SCOTT 1987-04-19 3,000.00 .00
7839 KING 1981-11-17 5,000.00 .00
7844 TURNER 1981-09-08 1,500.00 .00
7876 ADAMS 1987-05-23 1,100.00 .00
7900 JAMES 1981-12-03 950.00 .00
7902 FORD 1981-12-03 3,000.00 .00
7934 MILLER 1982-01-23 1,300.00 .00
IS_OPEN
函數IS_OPEN
用於測試是否已開啟一個遊標。
status BOOLEAN IS_OPEN(c INTEGER)
參數
參數名稱 | 描述 |
c | 待測試遊標的ID。 |
status | 如果遊標是開啟狀態,這個參數設為true。如果遊標沒有開啟,那麼這個值設為false。 |
LAST ROW COUNT
函數LAST_ROW_COUNT
返回當前已取回記錄的總數。
rowcnt INTEGER LAST_ROW_COUNT
參數
參數名稱 | 描述 |
rowcnt | 已取回記錄的總數。 |
樣本
在下面的樣本中,使用函數LAST_ROW_COUNT
查詢已取回記錄的總數。
DECLARE
curid INTEGER;
v_empno NUMBER(4);
v_ename VARCHAR2(10);
v_hiredate DATE;
v_sal NUMBER(7,2);
v_comm NUMBER(7,2);
v_sql VARCHAR2(50) := 'SELECT empno, ename, hiredate, sal, ' ||
'comm FROM emp';
v_status INTEGER;
BEGIN
curid := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(curid,v_sql,DBMS_SQL.native);
DBMS_SQL.DEFINE_COLUMN(curid,1,v_empno);
DBMS_SQL.DEFINE_COLUMN(curid,2,v_ename,10);
DBMS_SQL.DEFINE_COLUMN(curid,3,v_hiredate);
DBMS_SQL.DEFINE_COLUMN(curid,4,v_sal);
DBMS_SQL.DEFINE_COLUMN(curid,5,v_comm);
v_status := DBMS_SQL.EXECUTE(curid);
DBMS_OUTPUT.PUT_LINE('EMPNO ENAME HIREDATE SAL COMM');
DBMS_OUTPUT.PUT_LINE('----- ---------- ---------- -------- ' ||
'--------');
LOOP
v_status := DBMS_SQL.FETCH_ROWS(curid);
EXIT WHEN v_status = 0;
DBMS_SQL.COLUMN_VALUE(curid,1,v_empno);
DBMS_SQL.COLUMN_VALUE(curid,2,v_ename);
DBMS_SQL.COLUMN_VALUE(curid,3,v_hiredate);
DBMS_SQL.COLUMN_VALUE(curid,4,v_sal);
DBMS_SQL.COLUMN_VALUE(curid,4,v_sal);
DBMS_SQL.COLUMN_VALUE(curid,5,v_comm);
DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || RPAD(v_ename,10) || ' ' ||
TO_CHAR(v_hiredate,'yyyy-mm-dd') || ' ' ||
TO_CHAR(v_sal,'9,999.99') || ' ' ||
TO_CHAR(NVL(v_comm,0),'9,999.99'));
END LOOP;
DBMS_OUTPUT.PUT_LINE('Number of rows: ' || DBMS_SQL.LAST_ROW_COUNT);
DBMS_SQL.CLOSE_CURSOR(curid);
END;
顯示結果如下:EMPNO ENAME HIREDATE SAL COMM
----- ---------- ---------- -------- --------
7369 SMITH 1980-12-17 800.00 .00
7499 ALLEN 1981-02-20 1,600.00 300.00
7521 WARD 1981-02-22 1,250.00 500.00
7566 JONES 1981-04-02 2,975.00 .00
7654 MARTIN 1981-09-28 1,250.00 1,400.00
7698 BLAKE 1981-05-01 2,850.00 .00
7782 CLARK 1981-06-09 2,450.00 .00
7788 SCOTT 1987-04-19 3,000.00 .00
7839 KING 1981-11-17 5,000.00 .00
7844 TURNER 1981-09-08 1,500.00 .00
7876 ADAMS 1987-05-23 1,100.00 .00
7900 JAMES 1981-12-03 950.00 .00
7902 FORD 1981-12-03 3,000.00 .00
7934 MILLER 1982-01-23 1,300.00 .00
Number of rows: 14
OPEN_CURSOR
函數OPEN_CURSOR
用於建立一個新的遊標。您必須使用一個遊標來解析和執行動態SQL語句。當開啟遊標後,可以以相同或不同的SQL語句來重複使用這個遊標。您不需要通過關閉然後重新開啟的方式實現對遊標進行重用。
c INTEGER OPEN_CURSOR
參數
參數名稱 | 描述 |
c | 與新建立的遊標相關聯的遊標ID。 |
樣本
在下面的樣本中建立了一個新的遊標。
DECLARE
curid INTEGER;
BEGIN
curid := DBMS_SQL.OPEN_CURSOR;
.
.
.
END;
PARSE
預存程序PARSE
用於解析一條SQL命令或SPL代碼塊。如果SQL語句是一條DDL命令,那麼將立即執行這條命令,而不要求運行函數EXECUTE
。
PARSE(c INTEGER, statement VARCHAR2, language_flag INTEGER)
參數
參數名稱 | 描述 |
c | 一個已開啟遊標的ID。 |
statement | 已解析的SQL命令或SPL代碼塊。SQL命令不能以分號結束,而一個SPL代碼塊則要求以分號結束。 |
language_flag | 這個參數是為了與Oracle文法相容而提供的。使用DBMS_SQL.V6、DBMS_SQL.V7 或DBMS_SQL.native,實際上您可以忽略這個標誌,所有的文法都假定是以PolarDB PostgreSQL版(相容Oracle)的形式存在的。 |
樣本
下面的匿名代碼塊建立了名稱為job
的表。需要注意的是DDL語句是由預存程序PARSE
立即執行,不要求函數EXECUTE
單獨運行此步驟。
DECLARE
curid INTEGER;
BEGIN
curid := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(curid, 'CREATE TABLE job (jobno NUMBER(3), ' ||
'jname VARCHAR2(9))',DBMS_SQL.native);
DBMS_SQL.CLOSE_CURSOR(curid);
END;
以下代碼塊向表job
中插入兩條記錄。
DECLARE
curid INTEGER;
v_sql VARCHAR2(50);
v_status INTEGER;
BEGIN
curid := DBMS_SQL.OPEN_CURSOR;
v_sql := 'INSERT INTO job VALUES (100, ''ANALYST'')';
DBMS_SQL.PARSE(curid, v_sql, DBMS_SQL.native);
v_status := DBMS_SQL.EXECUTE(curid);
DBMS_OUTPUT.PUT_LINE('Number of rows processed: ' || v_status);
v_sql := 'INSERT INTO job VALUES (200, ''CLERK'')';
DBMS_SQL.PARSE(curid, v_sql, DBMS_SQL.native);
v_status := DBMS_SQL.EXECUTE(curid);
DBMS_OUTPUT.PUT_LINE('Number of rows processed: ' || v_status);
DBMS_SQL.CLOSE_CURSOR(curid);
END;
顯示結果如下:Number of rows processed: 1
Number of rows processed: 1
以下的匿名代碼塊使用DBMS_SQL包執行了包含2條INSERT語句的代碼塊。需要注意的是在代碼塊結束的地方包含一個分號結束符,而在OPEN_CURSOR中的樣本中,每個單獨的INSERT語句沒有分號結束符。
DECLARE
curid INTEGER;
v_sql VARCHAR2(100);
v_status INTEGER;
BEGIN
curid := DBMS_SQL.OPEN_CURSOR;
v_sql := 'BEGIN ' ||
'INSERT INTO job VALUES (300, ''MANAGER''); ' ||
'INSERT INTO job VALUES (400, ''SALESMAN''); ' ||
'END;';
DBMS_SQL.PARSE(curid, v_sql, DBMS_SQL.native);
v_status := DBMS_SQL.EXECUTE(curid);
DBMS_SQL.CLOSE_CURSOR(curid);
END;