PolarDB PostgreSQL版(兼容Oracle)還通過OPEN FOR USING語句支持動態查詢。字符串文字或字符串變量在OPEN FOR USING語句中提供給SELECT命令。
OPEN name FOR dynamic_string
[ USING bind_arg [, bind_arg_2 ] ...];
name是先前聲明的游標變量的標識符。dynamic_string是一個包含SELECT命令的字符串文字或字符串變量(沒有終止分號)。bind_arg, bind_arg_2... 是綁定參數,用于在游標變量打開時將變量傳遞給SELECT命令中的相應占位符。占位符是以冒號字符為前綴的標識符。
以下是使用字符串文字的動態查詢示例。
CREATE OR REPLACE PROCEDURE dept_query
IS
emp_refcur SYS_REFCURSOR;
v_empno emp.empno%TYPE;
v_ename emp.ename%TYPE;
BEGIN
OPEN emp_refcur FOR 'SELECT empno, ename FROM emp WHERE deptno = 30' ||
' AND sal >= 1500';
DBMS_OUTPUT.PUT_LINE('EMPNO ENAME');
DBMS_OUTPUT.PUT_LINE('----- -------');
LOOP
FETCH emp_refcur INTO v_empno, v_ename;
EXIT WHEN emp_refcur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || v_ename);
END LOOP;
CLOSE emp_refcur;
END;
以下是執行此存儲過程時的輸出。
EXEC dept_query;
EMPNO ENAME
----- -------
7499 ALLEN
7698 BLAKE
7844 TURNER
在下一個示例中,先前的查詢被修改為使用綁定參數來傳遞查詢參數。
CREATE OR REPLACE PROCEDURE dept_query (
p_deptno emp.deptno%TYPE,
p_sal emp.sal%TYPE
)
IS
emp_refcur SYS_REFCURSOR;
v_empno emp.empno%TYPE;
v_ename emp.ename%TYPE;
BEGIN
OPEN emp_refcur FOR 'SELECT empno, ename FROM emp WHERE deptno = :dept'
|| ' AND sal >= :sal' USING p_deptno, p_sal;
DBMS_OUTPUT.PUT_LINE('EMPNO ENAME');
DBMS_OUTPUT.PUT_LINE('----- -------');
LOOP
FETCH emp_refcur INTO v_empno, v_ename;
EXIT WHEN emp_refcur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || v_ename);
END LOOP;
CLOSE emp_refcur;
END;
下面是結果輸出。
EXEC dept_query(30, 1500);
EMPNO ENAME
----- -------
7499 ALLEN
7698 BLAKE
7844 TURNER
最后,使用字符串變量來傳遞SELECT,這可提供最大的靈活性。
CREATE OR REPLACE PROCEDURE dept_query (
p_deptno emp.deptno%TYPE,
p_sal emp.sal%TYPE
)
IS
emp_refcur SYS_REFCURSOR;
v_empno emp.empno%TYPE;
v_ename emp.ename%TYPE;
p_query_string VARCHAR2(100);
BEGIN
p_query_string := 'SELECT empno, ename FROM emp WHERE ' ||
'deptno = :dept AND sal >= :sal';
OPEN emp_refcur FOR p_query_string USING p_deptno, p_sal;
DBMS_OUTPUT.PUT_LINE('EMPNO ENAME');
DBMS_OUTPUT.PUT_LINE('----- -------');
LOOP
FETCH emp_refcur INTO v_empno, v_ename;
EXIT WHEN emp_refcur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_empno || ' ' || v_ename);
END LOOP;
CLOSE emp_refcur;
END;
EXEC dept_query(20, 1500);
EMPNO ENAME
----- -------
7566 JONES
7788 SCOTT
7902 FORD