全部產品
Search
文件中心

PolarDB:DBMS_SQL

更新時間:Jul 06, 2024

DBMS_SQL包提供查詢PolarDB PostgreSQL版(相容Oracle)動態SQL的功能,可以在應用運行時構建查詢。

PolarDB PostgreSQL版(相容Oracle)支援查詢動態SQL,且以與Oracle相容的方式來使用動態SQL。

表 1. DBMS_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包允許使用的公開變數。

表 2. DBMS_SQL 公開變數
公開變數資料類型取值說明
nativeINTEGER1與Oracle文法相容。更多資訊請參見DBMS_SQL.PARSE
V6INTEGER2與Oracle文法相容。更多資訊請參見DBMS_SQL.PARSE
V7INTEGER3與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。
nameSQL命令中綁定變數的名稱。
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。
nameSQL命令中綁定變數的名稱。
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。
nameSQL命令中綁定變數的名稱。
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的列empnoenamehiredatesalcomm

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;

下面顯示了針對上個樣本的另外一種實現方法,產生的結果完全一樣。需要注意的是與資料類型的長度無關。列empnosalcomm返回的資料長度分別等於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>類型的取值如下:
  • varchar2_table
  • clob_table
  • binary_float_table
  • binary_double_table
  • blob_table
  • date_table
  • number_table
  • timestamp_table
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_typeINTEGER
col_max_lenINTEGER
col_nameVARCHAR2(128)
col_name_lenINTEGER
col_schema_nameVARCHAR2(128)
col_schema_name_lenINTEGER
col_precisionINTEGER
col_scaleINTEGER
col_charsetidINTEGER
col_charsetformINTEGER
col_null_okBOOLEAN

EXECUTE

函數EXECUTE用於執行一個已解析SQL語句或SPL代碼塊。

status INTEGER EXECUTE(c INTEGER)
            

參數

參數名稱描述
c需要執行的SQL語句或SPL代碼塊的遊標ID,其中SQL命令已解析。
status如果SQL命令是DELETEINSERTUPDATE,那麼這個參數代表已處理的記錄數。如果是其它命令,那麼這個參數沒有意義。

樣本

下面的匿名代碼塊向表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
  • 設定為FALSE時,不產生異常。預設值為FALSE。
  • 設定為TRUE時,當結果集中的記錄數不等於1的時候,就會產生一個異常。
  • 設定為TRUE時,並且在結果集中沒有記錄,則會產生一個NO_DATE_FOUND的異常。
  • 設定為TRUE時,並且在結果集中有多條記錄的情況下,則會產生TOO_MANY_ROWS的異常。
status
  • 如果成功取回一條記錄,返回1。
  • 如果沒有取回記錄,返回0。
  • 如果產生異常的話,則不傳回值。

樣本

以下預存程序使用函數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;