+ All Categories
Home > Documents > 2008 Laoug2 Dynamic SQL

2008 Laoug2 Dynamic SQL

Date post: 06-Jul-2018
Category:
Upload: sbabuind
View: 219 times
Download: 0 times
Share this document with a friend

of 56

Transcript
  • 8/17/2019 2008 Laoug2 Dynamic SQL

    1/56

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    2/56

    2 of 56

    The Problem

    It is difficult to build a system that actually meets the

    stated requirements.

    Is the industry-wide 75% system failure rate still true?

    It is very difficult to build a system that doesn’t require

    massive changes within a short period of time. How many mistakes were made by previous contractors?

    It is impossible to build a system that will not be

    obsolete sooner or later. Did you ever meet anyone who is omniscient?

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    3/56

    3 of 56

    The Truth… Let’s be fair…

    I’ve never seen:

    100% perfect analysis 100% complete set of requirements

    100% adequate hardware

    100% competent users

    100% knowledgeable tech support

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    4/56

    4 of 56

    Not My Job

    Educate users

    Improve customer support

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    5/56

    5 of 56

    My Job

    Impossible Possible

    To do perfect analysis To identify directions

    To have completespecifications To define the most volatileareas

    To have the best possible

    hardware

    To build flexible

     performance tuning

    mechanisms

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    6/56

    6 of 56

    Unknowns

    What elements are involved?

    Example: The monthly summary table may not exist.

    What to do with the elements you have?

    Example: Do you need quarterly or yearly totals?

    How you should proceed?

    Example: Is a hash join hint the best option?

    Whether or not you can proceed?

    DDL is still prevented in PL/SQL, isn’t it?

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    7/56

    7 of 56

    The Hero

    Dynamic SQL:

    Makes it possible to build and process complete SQLand PL/SQL statements as strings at runtime.

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    8/56

    8 of 56

    Dynamic SQL & PL/SQL

    What does "dynamic" mean?

    Build a text string on the fly and execute it Very powerful technique

    Useful in many contexts

    What techniques exist?

    EXECUTE IMMEDIATE

    Dynamic cursors

    DBMS_SQL

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    9/56

    9 of 56

    Back to Basics:

    What are we talking about?

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    10/56

    10 of 56

    Dynamic SQL Core

    About 90% of dynamic SQL is covered by a singlecommand (with variations):

    decl ar ev_var i abl e_t x var char 2( 32000) ;

    begi n

    v_var i abl e_t x: ='   whatever_you_want';EXECUTE IMMEDIATE v_var i abl e_t x;end;

    OR 

    begi nEXECUTE IMMEDIATE '   whatever_you_want';

    end;

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    11/56

    11 of 56

    Dynamic Cursors

    Syntaxdecl ar e

    v_cur SYS_REFCURSOR;

    v_sql _t x var char 2( 32000) : =. . .

    v_r ec . . . %r owt ype; - - or r ecor d t ype

    begi n

    open v_cur for v_sql_tx;

    f et ch v_cur i nt o v_r ec;

    cl ose v_cur ;end;

    Most common use:

    Processing large datasets with unknown structure

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    12/56

    12 of 56

    DBMS_SQL package

    Predecessor of native dynamic SQL

    Pros:

    Goes above 32K in all versions

    Separates PARSE and EXECUTE

    The same query can be reused with different bind variables.

    Works with unknown number/type ofINPUT/OUTPUT values

    Cons: Usually slower (up to 5 times)

     No user-defined datatypes or output to the record.

    More difficult to use

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    13/56

    13 of 56

    Things to know (1)

    The code can be passed as a variable/string.

    The variable/string cannot exceed 32K, except In 11g – passing CLOB as input

    If the database is using fonts where 1 byte=1 char

     –up to 64K when concatenate a number of strings:

    execut e i mmedi at e

    v1_t xt | | v2_t xt | | v3_t xt | | …; In 8i and below – no limit on concatenation

    (undocumented feature - not supported by Oracle!)

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    14/56

    14 of 56

    Things to know (2)

    The variable/string can contain bind variables

    Start with a colon (:)

    Placeholders for values that will be supplied at

    runtime (USING and RETURNING clauses)

     No validation when compiled   No check for datatypes

     No check for passing enough values

     No direct limit on the number of bind variables.

    Like any other variables, they may be IN (default),

    OUT, or IN/OUT

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    15/56

    15 of 56

    Things to know (3)

    Bind variables are limited: CAN only be used to supply values to be passed to the code

    CANNOT be used to define the structural elements of queriesor PL/SQL blocks.

    Special cases: You cannot pass NULL as a literal.

    If statement has a RETURNING clause, it should be also usedin dynamic SQL.

    Bind variables may or may not be reusable

     NOT reusable in dynamic SQL – the number of variables isequal to the number of parameters.

    ARE reusable in dynamic PL/SQL – the number of UNIQUEvariables is equal to the number of parameters.

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    16/56

    16 of 56

    !!!REMEMBER!!!

    1. Use bind variables

    2. Use bind variables3. Use bind variables

    4. Use bind variables5. Use bind variables

    6. Use bind variables7. Use bind variables

    © Tom KyteP

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    17/56

    17 of 56

    Nightmare of SOX auditor (1)

    f unct i on F_GET_col _TX( i _t abl e_t x, i _showcol _t x, i _pkcol _t x, i _pkVal ue_nr )

    r et ur n var char 2 i sv_out _t x var char 2( 4000) ;

    v_sql_tx varchar2(32000);Begi n

    v_sql _t x: =

    ' sel ect t o_char ( ' | | i _showcol _t x| | ' ) ' | |' f r om ' | | i _t abl e_t x| |' wher e ' | | i _pkcol _t x| | ' =:v01' ;

    EXECUTE I MMEDI ATE v_sql _t x I NTO v_out _t xUSING i_pkValue_nr;

    r et ur n v_out _t x;

    end;

    M

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    18/56

    18 of 56

    Why do you still need DBMS_SQL?

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    19/56

    19 of 56

    Use Case

    The problem:

    Existing (ancient) UI generates query on the fly.

     No way to intercept generation  No way to have a limited number of possible cases

    Front-end is restricted to view only 500 rows.

     Need to generate complete result

    The solution:

    Generic query processor with a CLOB output (tab-delimited format)

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    20/56

    20 of 56

    Process Query (1) Parse query and get column list:

    FUNCTI ON f _get Quer y_cl ( i n_sql _t x, i _l i mi t _nr number : =64000)RETURN CLOB I S

    v_cur integer := dbms_sql.open_cursor;

    v_cols_nr number := 0;v_cols_tt dbms_sql.desc_tab;

    ...

    pr agma aut onomous_t r ansact i on;BEGI NDBMS_SQL.parse

    (v_cur, in_sql_tx, DBMS_SQL.native);

    DBMS_SQL.describe_cols(v_cur, v_cols_nr, v_cols_tt);

    FOR i I N 1 . . v_col s_nr LOOPv_col Li st _t x : =v_col Li st _t x | | ' | | chr ( 9) | | ' ' " ' ' | | v_quer y_t t ( i ) . ' | |

    v_cols_tt (i).col_name| | ' | | ' ' " ' ' ' ;v_header : = v_header | | chr ( 9) | | ' " ' | |

    v_cols_tt (i).col_name| | ' " ' ;END LOOP;

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    21/56

    21 of 56

    Process Query (2)

    Define a cursor in the dynamic block . . .v_pr ocess_t x : =' DECLARE

    v_out _cl CLOB;v_r ow_t x VARCHAR2( 32000) ;

    cursor c1 is '||in_sql_tx||';

    TYPE DynamicTable_tt IS TABLE OF c1%rowtype

    I NDEX BY BI NARY_I NTEGER;v_quer y_t t Dynami cTabl e_t t ;PROCEDURE p_addl i ne ( pi _t x VARCHAR2) I SBEGI N

    DBMS_LOB. wr i t eappend( v_out _cl , l engt h( pi _t x) , pi _t x) ;END;

    BEGI NDBMS_LOB. cr eat et empor ar y

    ( v_out _cl , TRUE, DBMS_LOB. CALL) ;p_addl i ne( : 1) ;. . .

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    22/56

    22 of 56

    Process Query (3)

    Execute the query. . .open c1;

    fetch c1 bulk collect

    into v_query_tt limit :2;cl ose c1;FOR i I N 1 . . v_quer y_t t . COUNT LOOP

    v_row_tx:='||v_colList_tx ||';

    p_addl i ne( v_r ow_t x) ;END LOOP;: 3 : = v_out _cl ;

    END; ' ;

    EXECUTE IMMEDIATE v_process_tx

    USING IN v_header, IN i_limit_nr,

    OUT v_out_cl;

    r et ur n v_out _cl ;END;

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    23/56

    23 of 56

    11g Additions

    Conversion between REF_CURSOR and

    DBMS_SQL cursor 

    DBMS_SQL.TO_REFCURSOR 

    DBMS_SQL.TO_CURSOR_NUMBER 

    P Q (1)

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    24/56

    24 of 56

    Process Query (1)

    Parse query and get column list:FUNCTI ON f _get Quer y_cl ( i n_sql _t x, i _l i mi t _nr )RETURN CLOB I Sv_cur i nt eger : = dbms_sql . open_cur sor ;

    v_col s_nr number : = 0;v_col s_t t dbms_sql . desc_t ab;v_execute_nr integer;

    v_ref_cur SYS_REFCURSOR;

    pr agma aut onomous_t r ansact i on;BEGI NDBMS_SQL. par se

    ( v_cur , i n_sql _t x, DBMS_SQL. nat i ve) ;

    DBMS_SQL. descr i be_col s( v_cur , v_col s_nr , v_col s_t t ) ;

    v_exec_nr:=dbms_sql.execute(v_cur);

    v_ref_cur:=dbm_sql.to_refcursor(v_cur);

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    25/56

    25 of 56

    Process Query (2)

    Define a cursor in the dynamic block . . .v_pr ocess_t x : =' DECLARE

    v_out _cl CLOB;v_r ow_t x VARCHAR2( 32000) ;

    cursor c1 is '||in_sql_tx||';

    TYPE DynamicTable_tt IS TABLE OF c1%rowtype

    I NDEX BY BI NARY_I NTEGER;v_quer y_t t Dynami cTabl e_t t ;PROCEDURE p_addl i ne ( pi _t x VARCHAR2) I SBEGI N

    DBMS_LOB. wr i t eappend( v_out _cl , l engt h( pi _t x) , pi _t x) ;END;

    BEGI NDBMS_LOB. cr eat et empor ar y

    ( v_out _cl , TRUE, DBMS_LOB. CALL) ;p_addl i ne( : 1) ;. . .

    Q ( )

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    26/56

    26 of 56

    Process Query (3)

    Execute the queryfetch :2 bulk collectinto v_query_tt limit :3;

    FOR i I N 1 . . v_quer y_t t . COUNT LOOP

    v_row_tx:='||v_colList_tx ||';

    p_addl i ne( v_r ow_t x) ;

    END LOOP;

    : 3 : = v_out _cl ;END; ' ;

    EXECUTE IMMEDIATE v_process_tx

    USING IN v_header ,

    IN v_ref_cursor,

    IN i_limit_nr, OUT v_out_cl;

    cl ose v_r ef _cur sor ;

    r et ur n v_out _cl ;END;

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    27/56

    27 of 56

    Security

    S it C

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    28/56

    28 of 56

    Security Concerns

    What privileges do you need to use dynamic

    SQL?

    How can you guard against misuse of dynamic

    SQL?

    G ti P i il (1)

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    29/56

    29 of 56

    Granting Privileges (1)

    All privileges have to be granted explicitly

    (Not via ROLES):

    System privileges

    cr eat e or r epl ace pr ocedur e p_makeTabl e( i _name_t x var char 2) i s

    begi n

    execut e i mmedi at e ' cr eat e t abl e '| | i _name_t x| | ' ( a_t x var char 2( 256) ) ' ;

    end;

    GRANT DBA to SCOTT … wrong!!!

    GRANT CREATE TABLE to SCOTT – correct!

    G ti P i il (2)

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    30/56

    30 of 56

    Granting Privileges (2)

    Object privileges

    f unct i on f _get Count _nr ( i _user _t x var char 2,

    i _t abl e_t x var char 2) r et ur n number i sbegi n

    execut e i mmedi at e ' sel ect count ( *) f r om '

    | | i _user _t x| | ' . ' | | i _t abl e_t x;end;

    GRANT DBA to SCOTT … wrong!!!

    GRANT SELECT on EMPLOYEE to SCOTT – correct!

    Fighting Code Injections

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    31/56

    31 of 56

    Fighting Code Injections

    DBA protection

    End users should not see administration tools

    UI protection

    User input should always be passed via bind variables

    (no concatenation!) Bind variables cannot affect the structure of the query.

    All structural selections should be made from the

    limited list of options (repository) Power users/developers populate the repository.

    End users only access whatever is already in the repository.

    Use Case

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    32/56

    32 of 56

    Use Case

    The problem:

    Large number of requests from the user interface

    Take some number of parameters Return something (search, extra info, status, etc.)

    The whole set of requests is not clear and may

    change each time.

    The solution:

    Universal wrapper Process all requests dynamically

    Storage (1)

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    33/56

    33 of 56

    Storage (1)

    Single table for both UI and server:cr eat e t abl e t _ext r a_ui( i d_nr number pr i mar y key,

    di spl ayName_t x var char 2( 256) ,f unct i on_t x var char 2( 50) ,v1_l abel _t x var char 2( 100) ,v1_t ype_t x var char 2( 50) ,

    v1_r equi r ed_yn var char 2( 1) ,v1_l ov_t x var char 2( 50) ,v1_conver t _t x var char 2( 50) ,

    . . . )Example:i nser t i nt o t _ext r a_ui ( …)

    val ues ( 1, ' Fi l t er Empl oyees' , ' f _get Emp_cl ' ,' J ob' , ' TEXT' , ' N' , nul l , nul l )

    Storage (2)

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    34/56

    34 of 56

    Storage (2) Published function

     ID_NR – unique ID of the function  DisplayName_tx – header of the screen

    ID and display are shown to users as LOV

     Function_tx – real function to be called 

    Parameters (never needed more than 10)  Vx_Label_tx – label for the parameter

    if null – parameter is disabled 

     Vx_Type_tx – helps UI to build the screen – can be: LOV – value list

    TEXT – free text

    DATE – attached calendar is needed   Vx_Required_yn – helps UI enforce needed parameters

     Vx_LOV_tx –name of the corresponding value list

     Vx_Convert_Tx – any expression with one input Example - 'to_date(:1, ''YYYYMMDD'')' – transformation to the real date

    Should always use bind variable with correct ID

    The Registered Function

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    35/56

    35 of 56

    The Registered Function

    f unct i on f_getEmp_CL ( i _j ob_t x var char 2) r et ur n CLOB i s

    v_out_cl CLOB;pr ocedur e p_add( pi _t x var char 2) i sbegi n

    dbms_l ob. wr i t eappend( v_out _cl , l engt h( pi _t x) , pi _t x) ;

    end;begi n

    dbms_l ob. cr eat et empor ar y( v_out _cl , t r ue, dbms_l ob. cal l ) ;

     p_add('');f or c i n ( sel ect ' ' | | ' ' | | empno| | ' ' | |

    ' ' | | ename| | ' ' | |' ' r ow_t x

    f r om emp wher e j ob = i _j ob_t x)l oop

    p_add( c. r ow_t x) ;end l oop;

     p_add('');r et ur n v_out _cl ;end;

    The Wrapper (1)

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    36/56

    36 of 56

    The Wrapper (1)

    f unct i on f_wrapper_cl ( i _i d_nr ,v1_tx var char 2: =nul l , . . . , v5_tx var char 2: =nul l )r et ur n CLOB i s

    v_out _cl CLOB;

    v_sql _t x var char 2( 2000) ;v_r ec t _ext r a_ui %r owt ype;

    begi nsel ect * i nt o v_r ec f r om t_extra_ui wher e i d_nr =i _i d_nr ;

    i f v_rec.v1_label_tx is not null t henv_sql _t x: =nvl ( v_rec.v1_convert_tx, ' :1' ) ;

    end i f ;. . .i f v_rec.v5_label_tx is not null t hen

    v_sql _t x: =v_sql _t x| | ' , ' | |

    nvl ( v_rec.v5_convert_tx, ' :5' ) ;end i f ;

    The Wrapper (2)

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    37/56

    37 of 56

    The Wrapper (2)v_sql _t x: =' begi n :out: =' | | v_rec.function_tx| |

    ' ( ' | | v_sql_tx| | ' ) ; end; ' ;

    i f v5_tx i s not nul l t henexecut e i mmedi at e v_sql _t xusing out v_out_cl, v1_tx,…,v5_tx;

    . . .el si f v1_tx i s not nul l t henexecut e i mmedi at e v_sql _t xusing out v_out_cl, v1_tx;

    el seexecut e i mmedi at e v_sql _t x using out v_out_cl;end i f ;

    r et ur n v_out _cl ;end;

    11g – Critical Addition

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    38/56

    38 of 56

    11g  Critical Addition

    DBMS_ASSERT – validating strings: SQL_OBJECT_NAME (string) – checks whether or

    not string is a valid object SIMPLE _SQL_NAME – checks whether or not string

    is a valid SQL name

    SCHEMA_NAME – validates that passed string is avalid schema

    ENQUOTE_NAME – adds a second quote to everyinstance in the name (and double quotes around)

    ENQOUTE_LITERAL – adds single quotes

    Nightmare of SOX auditor (2)

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    39/56

    39 of 56

    g ( )

    f unct i on F_GET_col _TX

    ( i _t abl e_t x, i _showcol _t x, i _pk_t x, i _pkVal ue_nr )r et ur n var char 2 i s

    v_out _t x var char 2( 4000) ;

    v_sql _t x var char 2( 32000) ;Begi n

    v_sql _t x: =

    ' sel ect t o_char ( ' | | i _showcol _t x| | ' ) f r om ' | |

    dbms_assert.simple_sql_name(i_table_tx)||' wher e ' | |

    dbms_assert.simple_sql_name(i_pk_tx)||

    | | ' =: v01' ;EXECUTE I MMEDI ATE v_sql _t x I NTO v_out _t x

    USI NG i _pkVal ue_nr ;

    r et ur n v_out _t x;

    end;

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    40/56

    40 of 56

    Object Dependencies

    Critical Point

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    41/56

    41 of 56

    Critical Point

    Dynamic SQL is executed at runtime, therefore:Bad things

     No dependencies to follow up No way to determine exactly what will be executed 

    Good things

    You can reference objects that may not be in the

    database (yet).

    You have a “back door” to resolve logical dead loopsor hide existing dependencies.

    How can you find dependencies?

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    42/56

    42 of 56

    How can you find dependencies?

    Use repositories:

    It is simple to compare your data to Oracle data

    dictionaries!Use samplers:

    Generate all possible (or as many as possible) permutations of the code to be executed and create

    PL/SQL modules with that code.

    Record all dependencies and keep a simple module thatreferences the same set of objects.

    If sampler becomes invalid, this means that you have

     problems.

    Why do you need a back door?

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    43/56

    43 of 56

    y do you eed a bac doo

    Code generators:

    Wrap call of generated modules into dynamic SQL

    Then you can refresh them without invalidating all

    dependencies

    Logical loops: Sometimes the simplest way out of the dependency

    loop is to convert one of the calls to dynamic SQL

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    44/56

    44 of 56

    Bulk Operations

    Supported Features

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    45/56

    45 of 56

    pp

     Native Dynamic SQL supports object collections

    and all kinds of operations on object collections:

    FORALL (Currently only in USING clause)

    BULK COLLECT

    DBMS_SQL supports only arrays as bulk list of bind variables

    Fixed in 11g!

    FORALL

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    46/56

    46 of 56

    FORALL – with limitations: In USING clause:

    Right:

    forall i in dept.first..dept.last

    execut e i mmedi at e

    ' del et e f r om emp wher e dept no=: 1' using dept(i);

    Wrong:

    forall i in dept.first..dept.last

    execut e i mmedi at e ' dr op t abl e t _' | | dept(i); The whole object only (fixed in 11g!)

    Right - dept(i)

    Wront - dept(i).deptno

    BULK COLLECT

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    47/56

    47 of 56

    Syntax:

    EXECUTE IMMEDIATE . . .

    BULK COLLECT INTO v_col l ect _t t ;Major advantages:

    Although dynamic SQL does not support any PL/SQLdatatypes, you can use RECORD as an output of a

    dynamic query.

    Dynamic SQL does support all user-defined SQL

    datatypes.

     And everybody forgets…

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    48/56

    48 of 56

    y y g

    Constructor should be used INSIDE of dynamic SQLtype lov_oty i s obj ect ( i d_nr …, di sp_t x…) ;type lov_nt as t abl e of l ov_ot y;

    f unct i on f _get Lov_nt( i _t abl e_t x, i _i d_t x, i _di sp_t x)

    r et ur n l ov_nt i s

    v_out_nt lov_nt := lov_nt();begi n

    execut e i mmedi at e ' sel ect lov_oty( '

    | | i _i d_t x| | ' , ' | | i _di sp_t x| | ' ) ' | |' f r om ' | | i _t abl e_t x bulk collect into v_out_nt;r et ur n v_out _nt ;

    end;

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    49/56

    49 of 56

    Performance

    andResource Utilization

    Keep in mind (Very Important!)

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    50/56

    50 of 56

    EXECUTE IMMEDIATE and dynamic cursors:

    If you use bind variables – 1 hard + N soft parses

    If you don’t use bind variables – N hard parses

    DBMS_SQL – the same plus: Extra option – only 1 parse

    Use Case

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    51/56

    51 of 56

    The problem:

    Users upload CSV files

     Name of file defines type Column headers map directly to table columns

    1 row of file = 1 logical group (1..N real rows)

    Group-level validation

    The solution:

    Universal CSV Loader  Build all inserts on the fly

    Build Insertsl

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    52/56

    52 of 56

    Decl ar e

    t ype i nt eger _t t i s t abl e of i nt eger ;v_cur_tt integer_tt;Begi nf or r i n v_gr oupRow_t t . f i r st . . v_gr oupRow_t t . l ast l oop

    v_cur_tt(r):=DBMS_SQL.OPEN_CURSOR;f or c i n c_col s( v_mapRows_t t ( r ) ) l oopf or i i n v_header _t t . f i r st . . v_header _t t . l ast l oop

    i f v_header _t t ( i ) . t ext =c. name_t x t henv_col _ t t ( i ) : =c;v_col _t x: =v_col _t x| | ' , ' | | v_col _t t ( i ) . vi ewcol _t x;v_val _t x: =v_val _t x| | ' , : ' | | v_col _t t ( i ) . vi ewcol _t x;

    end i f ;end l oop;

    end l oop;v_sql_tx:='insert into '||v_map_rec.view_tx||

    '('||v_col_tx||') values('||v_value_tx||')';

    DBMS_SQL.PARSE(v_cur_tt(r),v_sql_tx,DBMS_SQL.NATIVE);

    end l oop;

    Process Dataf i i 2 t t t

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    53/56

    53 of 56

    f or i i n 2. . v_r ow_t t . count

    l oopf or r i nv_gr oupRow_t t . f i r st . . v_gr oupRow_t t . l astl oop

    f or c i n v_col _t t . f i r st . . v_col _t t . l astl oop

    i f v_col _t t ( c) . i d = v_mapRows_t t ( r ) t hen

    DBMS_SQL.BIND_VARIABLE(v_cur_tt(r),':'||v_col_tt(c).viewcol_tx,

    v_data_tt(c).text);

    end i f ;end l oop;v_nr:=dbms_sql.execute(v_cur_tt(r));

    end l oop;end l oop;

    Best Practices

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    54/56

    54 of 56

    Whenever possible:

    Use BULK operations

    Minimize parsing

    Use bind variables

    Options to consider: Build a code repository

    Use generated code

    Summary

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    55/56

    55 of 56

    Dynamic SQL does:

    Significantly extend the list of available options for

    resolving many problems.

    Provide extra maneuvering room in production

    environments.Dynamic SQL should NOT:

     be considered a substitute for good analysis. be used where “regular” solutions are valid.

    Contact Information

  • 8/17/2019 2008 Laoug2 Dynamic SQL

    56/56

    56 of 56

    Dr. Paul Dorsey – [email protected] Michael Rosenblum – [email protected]

    Dulcian website - www.dulcian.com

    Developer AdvancedForms & ReportsDeveloper AdvancedForms & Reports Designer 

    Handbook

    Designer 

    Handbook

    Available now!

    Oracle PL/SQL for Dummies

    Design Using UMLObject ModelingDesign Using UMLObject Modeling


Recommended