Posted by: Edi Yanto on: April 14, 2007
Some programs must build and process a variety of SQL statements, where the exact text of the statement is unknown until run time. Such statements probably change from execution to execution. They are called dynamic SQL statements. Formerly, to execute dynamic SQL statements, you had to use the supplied package DBMS_SQL.
Now, within PL/SQL, you can execute any kind of dynamic SQL statement using an interface called native dynamic SQL.
The main PL/SQL features involved are the EXECUTE IMMEDIATE statement and cursor variables (also known as REF CURSOR).
Native dynamic SQL code is more compact and much faster than calling the DBMS_SQL package. The following example declares a cursor variable, then associates it with a dynamic SELECT statement:
DECLARE
TYPE EmpCurTyp IS REF CURSOR;
emp_cv EmpCurTyp;
v_name employees.last_name%TYPE;
v_sal employees.salary%TYPE;
my_sal NUMBER := 2000;
table_name VARCHAR2(30) := ‘employees’;
BEGIN
OPEN emp_cv FOR ‘SELECT last_name, salary FROM ‘ || table_name ||
‘ WHERE salary > ‘ || my_sal;
LOOP
FETCH emp_cv into v_name, v_sal;
EXIT WHEN emp_cv%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_name || ‘ ‘ || v_sal);
END LOOP;
CLOSE emp_cv;
END;
/
Consider a different type of PL/SQL application where SQL statements are built on the fly, based on a set of parameters specified at run-time. For example, an application might need to build various reports based on SQL statements where table and column names are not known in advance, or sorting and grouping of data is specified by a user requesting a report. Similarly, another application might need to create or drop tables or other database objects based on the action specified by a user at run-time. Because these SQL statements are generated on the fly and might change from time to time, so we need dynamic sql.
The use of dynamic SQL makes such applications flexible, versatile, and concise because it eliminates the need for complicated programming approaches.
Very helpful. Thanks!
@Edi Yanto: Useful – but clearly avoiding the real issue:
This example, though using IMMEDIATE, doesn’t solve anything, as the table name isn’t really variable, but known indirectly at compile type via the variable ‘table_name’.
The %rowtype is bound to table_name, which is (or should be), by problem defintion, unknown. We cannot use the %rowtype on a REF CURSOR, leaving us with the problem unsolved, as
“select * from table_name”
will not be parsable for any “table_name”s as we cannot resolve ‘*’ into any known %rowtype.
Feuerstein has a discussion of “Dynamic PL/SQL” in his “Oracle PL/SQL Programming”. As far as I can see, this (very tedious) method is the only way of solving the problem in a generic way.
If somebody has a better idea, please mail me!
BR
@edi…
i think what dan means is its not useful to use IMMEDIATE in your sample because its already know thaat table you going to select is “employee”. know not because you put it into variable but because you using
v_name employees.last_name%TYPE;
v_sal employees.salary%TYPE;
i think it would be a lot more better if you change this into
v_name varchar2(255);
v_sal number;
that make your code is not dependent to any table until run time.
May 17, 2007 at 9:53 pm
really nice programming
thanx a lot