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: 1BIND_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
2DESCRIBE_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: SALESFETCH_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 .00IS_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: 14OPEN_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;