Dynamic queries with cursor variables (PL/SQL)
The Db2® data server supports dynamic queries through the OPEN FOR statement in PL/SQL contexts.
Syntax
Description
- OPEN cursor-variable-name
- Specifies an identifier for a cursor variable that was previously declared within a PL/SQL context.
- FOR dynamic-string
- Specifies a string literal or string variable that contains a SELECT statement (without the terminating semicolon). The statement can contain named parameters, such as, for example, :param1.
- USING bind-arg
- Specifies one or more bind arguments whose values are substituted for placeholders in dynamic-string when the cursor opens.
Examples
The following example shows a dynamic
query that uses a string literal:
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;
The following example output is generated by the DEPT_QUERY
procedure:CALL dept_query;
EMPNO ENAME
----- -------
7499 ALLEN
7698 BLAKE
7844 TURNER
The query in the previous example
can be modified with bind arguments to pass the query parameters:
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;
The following CALL statement generates the same output
that was generated in the previous example:CALL dept_query(30, 1500);
A
string variable to pass the SELECT statement provides the most flexibility:
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;
This version of the DEPT_QUERY procedure generates
the following example output:CALL dept_query(20, 1500);
EMPNO ENAME
----- -------
7566 JONES
7788 SCOTT
7902 FORD