of 30
8/14/2019 native dynamic sql in plsql twp
1/30
Native Dynamic SQL:
A Better Alternative to DBM S_SQL
An Oracle Technical White Paper
M arch 199 9
8/14/2019 native dynamic sql in plsql twp
2/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
2
INTRODUCTION
Dynamic SQL adds power and flexibility to host languages (such as C, COBOL, etc.), by allowing
programs to accept and/or build SQL statements at run time. Dynamic SQL is required to build
applications where the text of the SQL statement is not known until execution time. For example,
dynamic SQL is needed for applications that allow users to choose query search criteria or optimizer
hint s at run time. These types of requirements are seen in:
= Database query tools.= Interactive database applications that present the user with information specific to their needs.= Application code that is reusable and, therefore, independent of the actual SQL statement
being executed.
Before Oracle8i, PL/SQL programs needed to use the DBMS_SQL package to execute SQL statements
dynamically. This is no longer essential. Native dynamic SQL in PL/SQL is easier to use than
DBMS_SQL, requires much less application code, and performs far better.
The organization of this paper is as follows:
= A description of the native dynamic SQL capability in PL/SQL.=
A description of the advantages of using native dynamic SQL. This section will enable the user tocompare it with the DBMS_SQL package approach.
= Typical usage examples.= Important performance tips for using native dynamic SQL.= A summary of this feature and future plans in this area.
8/14/2019 native dynamic sql in plsql twp
3/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
3
FEATURE DESCRIPTION
Native dynamic SQL provides the ability to dynamically execute SQL statements whose complete
text is not known until execution time. The dynamic statements could be data manipulation
language (DML) statements (including queries), PL/SQL anonymous blocks, data definition language
(DDL) statements, transaction control statements, session control statements, etc.
The following statements have been added/extended in PL/SQL, to support native dynamic SQL:
= EXECUTE IMMEDIATE prepares, executes, and deallocates a dynamic SQL statement.= OPEN The syntax of the OPEN cursor statement has been extended. It now supports opening
cursors on a dynamic SQL query that is specified as a string.
=FETCH, CLOSE The existing FETCH and CLOSE statements have been extended. Theysupport dynamic cursors without any syntax changes.
Also, bind arguments can be specified for the dynamic parameters in the EXECUTE IMMEDIATE
and OPEN statements. Native dynamic SQL includes the capability to bind to, or define a dynamic
statement, instances of any SQL data types supported in PL/SQL, and the ability to handle IN, IN
OUT, and OUT bind variables that are bound by position, not by name.
ADVANTAGES OF NATIVE DYNAMIC SQL
Compared to using the DBMS_SQL package, native dynamic SQL has several benefits, including ease
of use, improved performance, and the ability to overcome static SQL and the DBMS_SQL package
limitations. Of the benefits listed below, ease of use and performance provide the most significant
productivity benefits to the end-user.
EASE OF USE
The key motivation for providing native dynamic SQL support in PL/SQL is to make application
development using dynamic SQL statements very easy, compared to using the DBMS_SQL package.
This would be similar to using embedded static SQL statements in PL/SQL today.
8/14/2019 native dynamic sql in plsql twp
4/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
4
While DBMS_SQL is a PL/SQL library that offers a programmatic API to execute statements
dynamically, native dynamic SQL is an integral part of PL/SQL. Thus, a native dynamic SQL
program is much more readable and compact than an equivalent program that uses DBMS_SQL.
From looking at the example shown below, current users of the DBMS_SQL package will be able to
immediately see the benefits of this feature.
DM L Example using the
DBMS_SQL package
Equivalent DM L Example w ith
Native Dynamic SQL
procedure insert_into_table (table_name
varchar2,
deptnumber number, deptname
varchar2, location varchar2) is
cur_hdl integer;
stmt_str varchar2(200);
rows_processed binary_integer;
begin
stmt_str := 'insert into ' ||
table_name || ' values (:deptno,
:dname,
:loc)';
-- open cursor
cur_hdl := dbms_sql.open_cursor;
-- parse cursor
dbms_sql.parse(cur_hdl, stmt_str,
dbms_sql.native);
procedure insert_into_table
(table_name varchar2,
deptnumber number, deptname
varchar2, location varchar2) is
stmt_str varchar2(200);
begin
stmt_str := 'insert into ' ||
table_name || ' values (:deptno,
:dname,
:loc)';
8/14/2019 native dynamic sql in plsql twp
5/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
5
-- supply binds
dbms_sql.bind_variable(cur_hdl,
':deptno', deptnumber);
dbms_sql.bind_variable(cur_hdl,
':dname', deptname);
dbms_sql.bind_variable(cur_hdl,
':loc', location);
-- execute cursor
rows_processed :=
dbms_sql.execute(cur_hdl);
-- close cursor
dbms_sql.close_cursor(cur_hdl);
end;
EXECUTE IMMEDIATE stmt_str
USING
deptnumber, deptname, location;
end;
Finally, PL/SQLs seamless integration with SQL makes it an ideal choice for native dynamic SQL
programming. For instance, in Pro*C, a variables data portion and null portion are separately bound
to a SQL statement [4], whereas in PL/SQL it is sufficient to bind just the variable to
the SQL statement.
PERFORMANCE
Native dynamic SQL performs significantly better than DBMS_SQL, as the PL/SQL interpreter has
native support for native dynamic SQL. The DBMS_SQL approach is based on a procedural API,
and, as a result , suffers from high procedure call and data copy overhead. For example, on every bind,
the DBMS_SQL package implementation copies the PL/SQL bind variable into its space for use
8/14/2019 native dynamic sql in plsql twp
6/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
6
during the execution phase. Similarly, on every fetch, the data is first copied into the space that the
DBMS_SQL package manages and, subsequently, the fetched data is copied, one column at a time,
into the appropriate PL/SQL variables, which results in substantial data copying overhead.
Benchmark measurements, based on Oracle8i, were performed to compare the performance of
fetching a query and executing DML operations, using native dynamic SQL and the
DBMS_SQL package.
Our first benchmark was a dynamic query loop, where a cursor is opened on a query with 1 input
bind variable and 5 select columns. The result set is fetched, one row at a time, in each iteration of
the loop and no processing is done in the loop with the fetched data. The DBMS_SQL and native
dynamic SQL sources used for the query benchmark are given in Appendix A.1.
QUERY
LOOP
DBMS_SQL
(Ultra Sparc
Instruction Counts)
Native D ynamic
SQL
(Ultra Sparc
Instruction Counts)
Relative
Improvement
(Speedup)
1 iteration 218K 112K 1.9x
10 iterations 626K 248K 2.5x
100 iterations 5009K 1918K 2.6x
1000
iterations
45898K 15478K 2.9x
The second benchmark was an insert statement loop, where, for each iteration of the loop, one row is
dynamically inserted into a table with eight columns, with a different set of bind values each time.
The DBMS_SQL and native dynamic SQL sources used for the insert benchmark are given in
Appendix A.2.
8/14/2019 native dynamic sql in plsql twp
7/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
7
INSERT
LOOP
DBMS_SQL
(Ultra Sparc
Instruction Counts)
Native Dynamic
SQL
(Ultra Sparc
Instruction Counts)
Relative
Improvement
(Speedup)
1 iteration 396K 125K 3.2x
10 iterations 2188K 1222K 1.8x
100 iterations 23363K 15398K 1.5x
The above benchmark results show a 1.5x-3.2x improvement in performance by using native
dynamic SQL, instead of the DBMS_SQL package.
ABILITY TO OVERCOME STATIC SQL AND DBMS_SQL LIMITATIONS
The primary use for dynamic SQL, as described earlier, is in applications that do not know the entire
structure of the SQL or PL/SQL statement they need to process, until run time. However, native
dynamic SQL can also be used in situations, as shown below, where other approaches have
certain limitations.
= Limitations of Static SQL in PL/SQLCurrently, static SQL in PL /SQL does not support the T A BLE clause. T his limitati on can be overcome,
using native dynamic SQL, as shown in the example below:
create type t_emp as object(id number,name varchar(20));
create type t_emplist as table of t_emp;
create table dept(id number, emps t_emplist)
nested table emps store as emp_table;
8/14/2019 native dynamic sql in plsql twp
8/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
8
declare
deptid number;
ename varchar(20);
begin
EXECUTE IMMEDIATE 'select d.id, e.name
from dept d, TABLE(d.emps) e
where e.id = 1' INTO deptid, ename;
end;
= Limitations in the DBMS_SQL package N ative dynamic SQL can also be used for datatypes (such as objects, collections, and R EFs) that are notsupported i n t he DB M S_SQL package.
A lso, the use of % ROW T Y PE variables as fetch targets is not supported in the DBM S_SQL interface. In
native dynamic SQL, similar to static SQL in PL/SQL, the resultant rows of a query can be directly fetched
into PL/SQL records.
declare
emp_rec emp%ROWTYPE;
begin
stmt_str := 'select * from emp where job = :1';
8/14/2019 native dynamic sql in plsql twp
9/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
9
-- in a multi-row query
OPEN c FOR stmt_str USING `MANAGER';
loop
FETCH c INTO emp_rec;
EXIT WHEN c%NOTFOUND;
end loop;
CLOSE c;
-- in a single-row query
EXECUTE IMMEDIATE stmt_str INTO emp_rec
USING `PRESIDENT';
end;
TYPICAL USAGE OF NA TIVE DY NA M IC SQL
Having described the benefits of native dynamic SQL, we now highlight some typical examples to
illustrate the power, flexibility, and ease of use of this feature. These examples show how to use
native dynamic SQL to execute DDL and DML statements, execute single- and multiple-row queries,
and invoke PL/SQL blocks.
We will use a company's HR database as our working example and make the following assumptions
about the data model:
8/14/2019 native dynamic sql in plsql twp
10/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
10
= The list of all company locations is maintained in a master table, OFFICES. It has the followingstructure:
Column NameNull? Type
LOCATION NOT_NULL VARCHAR2(200)
= The employee information for each location is in a table, EMP_. (For example, employeeinformation for the company's Houston office is stored in the EMP_HOUSTON table). The
employee information tables have the following structure:
Column Name Null? Type
EMPNO NOT NULL NUMBER(4)
ENAME NOT NULL VARCHAR2(10)
JOB NOT NULL VARCHAR2(9)
SAL NOT NULL NUMBER(7,2)
DEPTNO NOT NULL NUMBER(2)
8/14/2019 native dynamic sql in plsql twp
11/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
11
DDL OPERATIONS
The EXECUTE IMMEDIATE statement can be used to perform DDL operations. For example, the
following procedures can be used to add and drop an office location.
procedure add_location (loc varchar2) is
begin
-- insert new location in master table
insert into OFFICES values (loc);
-- create an employee information table
EXECUTE IMMEDIATE
'create table ' || 'EMP_' || loc ||
'( EMPNO NUMBER(4) NOT NULL,
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
SAL NUMBER(7,2),
DEPTNO NUMBER(2)
8/14/2019 native dynamic sql in plsql twp
12/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
12
)';
end;
procedure drop_location (loc varchar2) is
begin
-- delete the employee table for location 'loc'
EXECUTE IMMEDIATE 'drop table ' || 'EMP_' || loc;
-- remove location from master table
delete from OFFICES where location = loc;
end;
DYNAMIC SINGLE-ROW QUERIES
The EXECUTE IMMEDIATE statement can be used to perform dynamic single-row queries. The
bind variables are specified in the USING clause, and the resultant row is fetched into the targets
specified in the INTO clause of the statement.
The following procedure retrieves the number of employees that are performing a specified job at a
particular location:
8/14/2019 native dynamic sql in plsql twp
13/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
13
function get_num_of_employees
(loc varchar2, job varchar2) return number is
begin
query_str := 'select count(*) from '
|| ' EMP_' || loc
|| ' where job = :job_title';
EXECUTE IMMEDIATE query_str
INTO num_of_employees
USING job;
return num_of_employees;
end;
DYNAMIC M ULTIPLE-ROW QUERIES
The OPEN, FETCH, and CLOSE statements can be used to perform dynamic multi-row queries.
The example below lists all the employees with a particular job title at a specified location.
procedure list_employees(loc varchar2, job varchar2) is
type cur_typ is REF CURSOR;
8/14/2019 native dynamic sql in plsql twp
14/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
14
c cur_typ;
...
begin
query_str := 'select ename, empno from EMP_' || loc
|| ' where job = :job_title';
-- find employees who perform the specified job
OPEN c FOR query_str USING job;
loop
FETCH c INTO emp_name, emp_num;
EXIT WHEN c%NOTFOUND;
-- process row here
end loop;
CLOSE c;
end;
8/14/2019 native dynamic sql in plsql twp
15/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
15
DM L OPERATIONS
The native dynamic SQL procedure shown below can be used for giving a raise to all employees with
a particular job title.
procedure salary_raise
(raise_percent number, job varchar2) is
type loc_array_type is table of varchar2(40)
index by binary_integer;
dml_str varchar2(200);
loc_array loc_array_type;
begin
-- bulk fetch the list of office locations
select location BULK COLLECT INTO loc_array
from OFFICES;
-- for each location, give a raise to employees with
-- the given 'job'
for i in loc_array.first..loc_array.last loop
8/14/2019 native dynamic sql in plsql twp
16/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
16
dml_str := 'update EMP_' || loc_array(i)
|| ' set sal = sal * (1+(:raise_percent/100))'
|| ' where job = :job_title';
EXECUTE IMMEDIATE dml_str USING raise_percent, job;
end loop;
end;
INVOKING DYNAMIC PL/SQL BLOCKS
The EXECUTE IMMEDIATE statement can also be used to invoke anonymous PL/SQL blocks. This
capability is very useful for application extension and customization, where the module to be
executed is determined dynamically at run-time.
Suppose you want to write an event dispatcher that takes an event number and dispatches to a
handler for the event that is of the form EVENT_HANDLER_. One approach would
be to implement the dispatcher as a switch statement, as shown below, where the code handles each
event by making a static call to its appropriate handler.
procedure event_dispatcher
(event number, param number) is
begin
if (event = 1) then
EVENT_HANDLER_1(param);
8/14/2019 native dynamic sql in plsql twp
17/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
17
elsif (event = 2) then
EVENT_HANDLER_2(param);
elsif (event = 3) then
EVENT_HANDLER_3(param);
end if;
end;
The above piece of code is not very extensible, because the dispatcher code needs to be updated
whenever a handler for a new event is added. However, using native dynamic SQL you could write
an extensible event dispatcher as shown below:
procedure event_dispatcher
(event number, param number) is
begin
EXECUTE IMMEDIATE
'begin
EVENT_HANDLER_' || to_char(event) || '(:1);
end;'
USING param;
end;
8/14/2019 native dynamic sql in plsql twp
18/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
18
PERFORM ANCE TIPS
The performance of PL/SQL applications that use native dynamic SQL can be significantly improved,
by utilizing some of the performance tips described below:
= Use bind variables to improve cursor sharingW henever possible, use bind variables to parameterize your statement. T hat enables you to reuse the
associated cursor for different sets of input values.
For example, the following statement does not use bind variables. For each distinct "my_deptno," a new
cursor will be built, resulting in hard-parses and causing serious library cache contention.
EXECUTE IMMEDIATE 'DELETE FROM dept WHERE deptno = ' ||
to_char(my_deptno);
T he preferred approach is to bind "my_deptno" as a bind variable, as shown below. T he same cursor wi ll be
reused for different values of the bind my_deptno, and, thus, it performs and scales better.
EXECUTE IMMEDIATE 'DELETE FROM dept WHERE deptno = :1' USING
my_deptno;
= Simulate bulk SQL operations in native dynamic SQL In Oracle8i PL /SQL, bulk bind operat ions are supported for processing stat ic SQL statements. T hissignificantly improves the efficiency of multiple row fetches/inserts, by minimizing context switching between
PL/SQL and SQL.
A lthough there is no direct support f or bulk operations in native dynamic SQL statements, wrapping the bulk
SQL statement in a 'B EG IN ..EN D' block, and then executing the block, dynamically enables the PL/SQL
block to treat the inner SQL statement as static.
T he example shown below can be used to copy the "ename" column of one table to another:
create type NAME_ARRAY_TYPE is
VARRAY(100) of VARCHAR2(50);
8/14/2019 native dynamic sql in plsql twp
19/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
19
procedure copy_ename_column
(table1 varchar2, table2 varchar2) is
ename_col NAME_ARRAY_TYPE;
begin
-- bulk fetch the 'ename' column into a VARRAY of
-- VARCHAR2s.
EXECUTE IMMEDIATE
'begin
select ename BULK COLLECT INTO :tab
from ' || table1 || ';
end;'
USING OUT ename_col;
-- insert the 'ename' column into another table.
EXECUTE IMMEDIATE
'begin
8/14/2019 native dynamic sql in plsql twp
20/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
20
FORALL i in :first .. :last
insert into ' || table2 || ' values (:tab(i));
end;'
USING ename_col.first, ename_col.last, ename_col;
end;
A nother alternative is to fetch multiple rows in bulk , using the M U LT ISET and CA ST operations. T he
sample code shown below fetches the 'ename' column of a table (given the table's name):
procedure get_ename_column
(table_name varchar2, ename_col OUT NAME_ARRAY_TYPE) is
begin
EXECUTE IMMEDIATE
'select
CAST(MULTISET(select ename from ' ||
table_name || ')
as NAME_ARRAY_TYPE)
from dual'
INTO ename_col;
end;
8/14/2019 native dynamic sql in plsql twp
21/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
21
SUMMARY
As discussed in this paper, native dynamic SQL provides two key benefits over its current alternative,
the DBMS_SQL package, namely, performance and ease of use. Dynamic SQL applications in
PL/SQL can benefit from a 1.5x-3.2x improvement in performance, by using native dynamic SQL,
instead of the DBMS_SQL package. Also, dynamic SQL eases application development and results in
compact code that is easy to maintain and enhance. These benefits make native dynamic SQL a very
attractive solution for developing large applications, while keeping the code base compact.
Significant improvements are planned that will extend the capabilities of native dynamic SQL.
Support for bulk dynamic SQL in the future would allow users to process multiple rows of data in a
single DML statement, where the DML statement is a dynamic SQL statement. This would result in
substantial performance improvements, by minimizing context switching between SQL and PL/SQL.
Another enhancement planned is support for explicit dynamic statement management. This will
allow a dynamic statement to be executed several times with different sets of bind variables, without
incurring the statement preparation overhead for each execution. We also plan to provide a dynamic
describe capability, similar to that in the DBMS_SQL package, that will enable a developer to writ e
applications that need to deal with dynamic queries whose shape (i.e. structure of query columns) is
known only at run-time. These enhancements will build upon the current benefits of using native
dynamic SQL, making it an extremely powerful tool for PL/SQL application developers.
REFERENCES
1. PL/SQL Users Guide and Reference, Oracle8i, Version 8.1, 1998.
2. Oracle8i Server Application Developers Guide, Version 8.1, 1998.
3. Understanding the New SQL: A Complete Guide, Jim Melton & Alan R. Simon, 1993.
4. Programmers Guide to the Pro*C/C++ Precompiler, Release 8.0, 1997.
5. Database Language SQL- Part 4: Persistent Stored Modules, Mar 1997, ISO Working Draft.
6. Database Language SQL- Part 5: Host language bindings, April 1997, ISO Working Draft.
8/14/2019 native dynamic sql in plsql twp
22/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
22
APPENDIX A: SOURCES USED FOR PERFORMA NCE BENCHM ARKS
In this section the sources used for the performance benchmarks mentioned in the section titled
Performance are provided.
The create table statement for the EMP table used for running the dynamic QUERY and INSERT
benchmarks is shown below.
CREATE TABLE EMP
( EMPNO NUMBER(4) NOT NULL,
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7,2),
COMM NUMBER(7,2),
DEPTNO NUMBER(2) NOT NULL);
QUERY BENCHMARK
DBMS_SQL Implementation
-- Query loop using DBMS_SQL package
create or replace procedure DBMSSQL_QUERY is
cur_hdl integer;
stmt_str varchar2(200);
rows_processed binary_integer;
enum number;
8/14/2019 native dynamic sql in plsql twp
23/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
23
name varchar2(200);
deptno number;
salary number;
hiredate date;
begin
stmt_str := 'select empno, ename, hiredate, sal, deptno
from emp
where job = :jobname';
cur_hdl := dbms_sql.open_cursor;
dbms_sql.parse(cur_hdl, stmt_str, dbms_sql.native);
-- supply binds
dbms_sql.bind_variable(cur_hdl, 'jobname', 'SALESMAN');
-- describe defines
dbms_sql.define_column(cur_hdl, 1, enum);
dbms_sql.define_column(cur_hdl, 2, name, 200);
dbms_sql.define_column(cur_hdl, 3, hiredate);
dbms_sql.define_column(cur_hdl, 4, salary);
dbms_sql.define_column(cur_hdl, 5, deptno);
-- execute cursor
8/14/2019 native dynamic sql in plsql twp
24/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
24
rows_processed := dbms_sql.execute(cur_hdl);
loop
-- fetch a row
if dbms_sql.fetch_rows(cur_hdl) > 0 then
-- fetch columns from the row
dbms_sql.column_value(cur_hdl, 1, enum);
dbms_sql.column_value(cur_hdl, 2, name);
dbms_sql.column_value(cur_hdl, 3, hiredate);
dbms_sql.column_value(cur_hdl, 4, salary);
dbms_sql.column_value(cur_hdl, 5, deptno);
else
exit;
end if;
end loop;
-- close cursor
dbms_sql.close_cursor(cur_hdl);
end;
8/14/2019 native dynamic sql in plsql twp
25/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
25
Native Dynamic SQL Implementation
-- Query loop using Native Dynamic SQL package
create or replace procedure NDSQL_QUERY is
type rct is REF CURSOR;
c rct;
stmt_str varchar2(200);
enum number;
name varchar2(200);
deptno number;
salary number;
hiredate date;
begin
stmt_str := 'select empno, ename, hiredate, sal, deptno
from emp
where job = :jobname';
OPEN c FOR stmt_str USING 'SALESMAN';
loop
FETCH c INTO enum, name, hiredate, salary, deptno;
EXIT WHEN c%NOTFOUND;
end loop;
CLOSE c;
end;
8/14/2019 native dynamic sql in plsql twp
26/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
26
INSERT BENCHMARK
DBMS_SQL Implementation
-- Insert loop using DBMS_SQL package.
create or replace procedure DBMSSQL_DML
(number_of_rows binary_integer) is
cur_hdl integer;
stmt_str varchar2(200);
rows_processed binary_integer;
empno number(4);
ename varchar2(10);
job varchar2(9);
mgr number(4);
hiredate date;
sal number(7,2);
comm number(7,2);
deptno number(2);
begin
stmt_str := 'insert into emp values(:empno,:ename,:job,:mgr,
:hiredate,:sal,:comm,:deptno)';
8/14/2019 native dynamic sql in plsql twp
27/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
27
-- open cursor
cur_hdl := dbms_sql.open_cursor;
-- parse cursor
dbms_sql.parse(cur_hdl, stmt_str, dbms_sql.native);
-- supply binds
job := 'SALESMAN';
hiredate := '17-DEC-80';
sal := 2000;
comm := 200;
deptno := 15;
for idx in 1..number_of_rows loop
empno := idx;
ename := 'EMP_' || to_char(idx);
mgr := idx;
dbms_sql.bind_variable(cur_hdl, ':empno', empno);
dbms_sql.bind_variable(cur_hdl, ':ename', ename);
dbms_sql.bind_variable(cur_hdl, ':job', job);
dbms_sql.bind_variable(cur_hdl, ':mgr', mgr);
dbms_sql.bind_variable(cur_hdl, ':hiredate', hiredate);
dbms_sql.bind_variable(cur_hdl, ':sal', sal);
8/14/2019 native dynamic sql in plsql twp
28/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
28
dbms_sql.bind_variable(cur_hdl, ':comm', comm);
dbms_sql.bind_variable(cur_hdl, ':deptno', deptno);
-- execute cursor
rows_processed := dbms_sql.execute(cur_hdl);
end loop;
-- close cursor
dbms_sql.close_cursor(cur_hdl);
end;
Native Dynamic SQL Implementation
-- Insert loop using Native Dynamic SQL package
create or replace procedure NDSQL_DML
(number_of_rows binary_integer) is
stmt_str varchar2(200);
empno number(4);
ename varchar2(10);
job varchar2(9);
mgr number(4);
hiredate date;
sal number(7,2);
comm number(7,2);
deptno number(2);
8/14/2019 native dynamic sql in plsql twp
29/30
Native Dynamic SQL: A Better Alternative to DBMS_SQL
March 1999
29
begin
stmt_str := 'insert into emp values
(:1,:2,:3,:4,:5,:6,:7,:8)';
-- supply binds
job := 'SALESMAN';
hiredate := '17-DEC-80';
sal := 2000;
comm := 200;
deptno := 15;
for idx in 1..number_of_rows loop
empno := idx;
ename := 'EMP_' || to_char(idx);
mgr := idx;
EXECUTE IMMEDIATE stmt_str
USING empno, ename, job, mgr, hiredate, sal, comm,
deptno;
end loop;
end;
8/14/2019 native dynamic sql in plsql twp
30/30
Oracle Corporation
World Headquarters
500 Oracle Parkway
Redwood Shores, CA 94065U.S.A.
Worldwide Inquiries:
+1.650.506.7000
Fax +1.650.506.7200
http:// ww w.oracle.com/
Copyright Oracle Corporation 1999
All Rights Reserved
This document is provided for informational purposes only, and
the information herein is subject to change without notice.
Please report any errors herein to Oracle Corporation. Oracle
Corporation does not provide any warrant ies covering and
specifically disclaims any liability in connection w ith t his
document.
Oracle is a registered trademark, and Oracle8i, Oracle8, PL/SQL,
and Oracle Expert are t rademarks or registered trademarks of
Oracle Corporation. All other company and product names
mentioned are used for identi fication purposes only and may be
trademarks of their respective owners.