native dynamic sql in plsql twp

download native dynamic sql in plsql  twp

of 30

Transcript of native dynamic sql in plsql twp

  • 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.