Execute immediate and dynamic sql

Dear all;
Just curious....Why do developers still use dynamic sql..and execute immediate, because I always thought dynamic sql were bads and the use of execute immediate as well...
or am I missing something...

There are no 'bad' things and 'good' things.
There are 'correctly used' and 'incorrectly used' features.
It depends what you want to do.
One simple example: Oracle 11.2 - you write a package that fetches data from range interval partitioned table (a new partition is created automatically every day when new key values are inserted). If you use static SQL then whenever Oracle creates a new partition then your package gets invalidated and has to be compiled. If your package is heavily used (by many sessions running in parallel) then you may get this:
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body "PACKAGE.XXXXX" has been invalidated
ORA-06508: PL/SQL: could not find program unit being called: "PACKAGE.XXXXX" Nice, isn't it?
You can avoid this kind of problems by simply using dynamic SQL. You break dependency with the table and your package is not invalidated when new partition is created.

Similar Messages

  • Error while insert data using execute immediate in dynamic table in oracle

    Error while insert data using execute immediate in dynamic table created in oracle 11g .
    first the dynamic nested table (op_sample) was created using the executed immediate...
    object is
    CREATE OR REPLACE TYPE ASI.sub_mark AS OBJECT (
    mark1 number,
    mark2 number
    t_sub_mark is a class of type sub_mark
    CREATE OR REPLACE TYPE ASI.t_sub_mark is table of sub_mark;
    create table sam1(id number,name varchar2(30));
    nested table is created below:
    begin
    EXECUTE IMMEDIATE ' create table '||op_sample||'
    (id number,name varchar2(30),subject_obj t_sub_mark) nested table subject_obj store as nest_tab return as value';
    end;
    now data from sam1 table and object (subject_obj) are inserted into the dynamic table
    declare
    subject_obj t_sub_mark;
    begin
    subject_obj:= t_sub_mark();
    EXECUTE IMMEDIATE 'insert into op_sample (select id,name,subject_obj from sam1) ';
    end;
    and got the below error:
    ORA-00904: "SUBJECT_OBJ": invalid identifier
    ORA-06512: at line 7
    then when we tried to insert the data into the dynam_table with the subject_marks object as null,we received the following error..
    execute immediate 'insert into '||dynam_table ||'
    (SELECT

    887684 wrote:
    ORA-00904: "SUBJECT_OBJ": invalid identifier
    ORA-06512: at line 7The problem is that your variable subject_obj is not in scope inside the dynamic SQL you are building. The SQL engine does not know your PL/SQL variable, so it tries to find a column named SUBJECT_OBJ in your SAM1 table.
    If you need to use dynamic SQL for this, then you must bind the variable. Something like this:
    EXECUTE IMMEDIATE 'insert into op_sample (select id,name,:bind_subject_obj from sam1) ' USING subject_obj;Alternatively you might figure out to use static SQL rather than dynamic SQL (if possible for your project.) In static SQL the PL/SQL engine binds the variables for you automatically.

  • Difference between Static SQL Query and Dynamic SQL Query.

    Hi,
    Please explain the basic difference between static and dynamic sql queries. Please explain with example.

    Static: http://download.oracle.com/docs/cd/E11882_01/appdev.112/e10472/static.htm
    Dynamic: http://download.oracle.com/docs/cd/E11882_01/appdev.112/e10472/dynamic.htm

  • Pivot and dynamic SQL

    Hi Team,
    I need to write a SQL to cater the requirements. Below is my requirements:
    pagename fieldname fieldvalue account_number consumerID
    AFAccountUpdate ArrangementsBroken dfsdff 1234 1234
    AFAccountUpdate ArrangementsBroken1 dfsdff 1234 1234
    AFAccountUpdate ArrangementsBroken2 dfsdff 1234 1234
    AFAccountUpdate ArrangementsBroken2 dfsdff 12345 12345
    AFAccountUpdate ArrangementsBroken1 addf 12345 12345
    Create table test_pivot_dynamic
    pagename varchar(200),
    fieldname Varchar(200),
    fieldvalue varchar(500),
    N9_Router_Account_Number bigint,
    TC_Debt_Item_Reference bigint
    --Input
    insert into test_pivot_dynamic Values('AFAccountUpdate','ArrangementsBroken','addf',1234,1234)
    insert into test_pivot_dynamic Values('AFAccountUpdate','ArrangementsBroken1','dfsdff',1234,1234)
    insert into test_pivot_dynamic Values('AFAccountUpdate','ArrangementsBroken2','fder',1234,1234)
    insert into test_pivot_dynamic Values('AFAccountUpdate','ArrangementsBroken2','dfdfs',12345,12345)
    insert into test_pivot_dynamic Values('AFAccountUpdate','ArrangementsBroken1','dfdwe',12345,12345)
    insert into test_pivot_dynamic Values('AFAccountUpdate1','Arrangements','addf',1234,1234)
    insert into test_pivot_dynamic Values('AFAccountUpdate1','Test1','dfsdff',1234,1234)
    --Expected output:
    Select 1234,1234,'AFAccountUpdate','ArrangementsBroken','addf','ArrangementsBroken1','dfsdff','ArrangementsBroken2','fder','ArrangementsBroken2','fder'
    Select 12345,12345,'AFAccountUpdate','ArrangementsBroken','addf','ArrangementsBroken1','dfdwe','ArrangementsBroken2','dfdfs'
    Select 1234,1234,'AFAccountUpdate1','Arrangements','addf','Test1','dfsdff'
    so basically we have to pivot and dynamic sql and insert the expected output to a common table which will have all the required fields
    Thanks,Ram.
    Please don't forget to Marked as Answer if my post solved your problem and use Vote As Helpful if a post was useful. It will helpful to other users.

    This should give you what you're looking for
    SELECT N9_Router_Account_Number,TC_Debt_Item_Reference,PageName,
    MAX(CASE WHEN SEQ = 1 THEN fieldname END) AS fieldname1,
    MAX(CASE WHEN SEQ = 1 THEN fieldvalue END) AS fieldvalue1,
    MAX(CASE WHEN SEQ = 2 THEN fieldname END) AS fieldname2,
    MAX(CASE WHEN SEQ = 2 THEN fieldvalue END) AS fieldvalue2,
    MAX(CASE WHEN SEQ = 3 THEN fieldname END) AS fieldname3,
    MAX(CASE WHEN SEQ = 3 THEN fieldvalue END) AS fieldvalue3,
    MAX(CASE WHEN SEQ = 4 THEN fieldname END) AS fieldname4,
    MAX(CASE WHEN SEQ = 4 THEN fieldvalue END) AS fieldvalue4
    FROM
    SELECT *,ROW_NUMBER() OVER (PARTITION BY N9_Router_Account_Number,TC_Debt_Item_Reference,PageName ORDER BY PageName) AS SEQ,*
    FROM test_pivot_dynamic
    )t
    GROUP BY N9_Router_Account_Number,TC_Debt_Item_Reference,PageName
    To make it dynamic see
     http://www.beyondrelational.com/modules/2/blogs/70/posts/10791/dynamic-crosstab-with-multiple-pivot-columns.aspx
    Please Mark This As Answer if it helps to solve the issue Visakh ---------------------------- http://visakhm.blogspot.com/ https://www.facebook.com/VmBlogs

  • Strange Case on Security Rights and Dynamic SQL (Execute Immediate)

    Hi friends, (forgive me if I write with wrong grammar and sentence, I not used English for daily)
    I got a weird trouble yesterday.
    I created a package (we can called it X, OK!?) which containing Execute Immediate Statement, that function to delete a table (we can called it Y).
    Several days ago, it's worked, but yesterday it wasn't. Last things happened before was recreate those table, and regrant to a role which including user account that execute package X.
    Error Msg shown is ORA-00942 : Table or view does not exist. After rechecked and rechecked, I found nothing that could trigger that error, I used DBMS_OUTPUT.PUT_LINE to debug and show what statement resulted and executed, I cut and paste, and it's worked. I created anonymous PL/SQL Block, and wrote it and executed it, and worked.
    Finally, today, We Grant explicitly those table to user account Y, not via Role, ... and it's work. Interesting thing I think :P
    And, I revoke, execute package and run. I think, there's something about Oracle he..he.. :D .
    Can somebody help me and explain me the reason of that strange symptomp? and right solution? I must know it, because several days again, it's launched / install.
    TIA

    Here is the procedure that get troubled into :)
    PROCEDURE DeleteOld_Job(
    p_Job_Code IN VARCHAR2,
    p_User_Id IN VARCHAR2,
    p_Parameter_Entry IN VARCHAR2,
    p_Status OUT NUMBER )
    IS
    StrSql VARCHAR2(1000);
    CURSOR CTable_Used_By_Report IS
    SELECT TABLE_NAME
    ,TABLE_OWNER
    FROM TABLE_USED_BY_JOB
    WHERE
    Job_Code = p_Job_Code
    BEGIN
    p_Status := 1;
    DBMS_OUTPUT.PUT_LINE('p_Job_Code '| |p_Job_Code );
    DBMS_OUTPUT.PUT_LINE('p_Parameter_Entry '| |p_Parameter_Entry );
    FOR Item IN CTable_Used_By_Report
    LOOP
    StrSql := 'DELETE '| |Item.TABLE_OWNER| |'.'| |Item.TABLE_NAME| |' T WHERE EXISTS ( SELECT 1 FROM USERBATCH.HISTORY_JOB H WHERE H.USER_ID = ' ;
    StrSql := StrSql| |''''| |p_User_Id| |''''| |' AND H.Job_Code = '| |''''| |p_Job_Code| |''''| |' AND H.PARAMETER_ENTRY = '| |'''' | |p_Parameter_Entry| |''''| |' AND T.SESSION_ID = H.TRANSACTION_ID)';
    DBMS_OUTPUT.PUT_LINE(StrSql);
    DBMS_OUTPUT.PUT_LINE(Item.TABLE_OWNER| |'.'| |Item.TABLE_NAME);
    EXECUTE IMMEDIATE StrSql;
    END LOOP;
    DBMS_OUTPUT.PUT_LINE('DELETE USERBATCH.HISTORY_JOB WHERE USER_ID ='''| | p_User_Id | |'''
    AND Job_Code ='''| | p_Job_Code | |''' AND PARAMETER_ENTRY = '''| | p_Parameter_Entry | |'''');
    EXECUTE IMMEDIATE 'DELETE USERBATCH.HISTORY_JOB WHERE USER_ID ='''| | p_User_Id | |'''
    AND Job_Code ='''| | p_Job_Code | |''' AND PARAMETER_ENTRY = '''| | p_Parameter_Entry | |'''';
    COMMIT;
    EXCEPTION
    WHEN OTHERS THEN
    ROLLBACK;
    p_Status := 0;
    DBMS_OUTPUT.PUT_LINE( SUBSTR(SQLERRM,1,255) );
    END DeleteOld_Job;
    TIA
    null

  • PL/SQL Proc, execute immediate and materialized view 9.2.0.6

    Hello,
    Environement description: Sun Solaris 8 , Oracle database 9.2.0.6
    I've a problem trying to execute this PL/SQL Procedure:
    I'm loged in with PMU user
    CREATE OR REPLACE PROCEDURE PMU.PROC_TEST_PMU_C035 (part_arrete in integer, part_session in integer) AS
    lv_p_arrete number     := part_arrete;
    lv_p_session number     := part_session;
    lv_stmt     varchar2(31000);
    BEGIN
    lv_stmt := ' ';
    lv_stmt := lv_stmt || 'CREATE MATERIALIZED VIEW 'PMU''.''TEST_PMU_C035'' ';
    lv_stmt := lv_stmt || 'TABLESPACE PMU_8M_DATA ';
    lv_stmt := lv_stmt || 'BUILD IMMEDIATE ';
    lv_stmt := lv_stmt || 'REFRESH COMPLETE AS ';
    lv_stmt := lv_stmt || 'SELECT * FROM ACTION ';
    lv_stmt := lv_stmt || 'WHERE LIBELLE IN ( ''SOCIETE 1'', ''SOCIETE 2'', ''SOCIETE 3'' ) ;';
    dbms_output.put_line ( lv_stmt) ;
    execute immediate ( lv_stmt);
    END;
    When I comment the line : execute immediate ( lv_stmt); It works fine and my statement appear on the screen:
    CREATE MATERIALIZED VIEW PMU.TEST_PMU_C035 TABLESPACE PMU_8M_DATA BUILD
    IMMEDIATE REFRESH COMPLETE AS SELECT LIBELLE FROM ACTION WHERE LIBELLE IN (
    'SOCIETE1', 'SOCIETE2', 'SOCIETE3' ) ;
    When I execute manually this query it works.
    But when I try to do the execute immediate, it gives me this error:
    BEGIN "PMU"."PROC_TEST_PMU_C035" ( 13, 14); END;
    ERROR at line 1:
    ORA-00911: invalid character
    ORA-06512: at "PMU.PROC_TEST_PMU_C035", line 15
    ORA-06512: at line 1
    Action Table has this description and datas:
    SQL> desc action
    Name Null? Type
    ISIN NOT NULL VARCHAR2(20)
    LIBELLE VARCHAR2(100)
    SQL>
    ISIN LIBELLE
    FR1 SOCIETE 1
    FR2 SOCIETE 2
    FR3 SOCIETE 3
    FR4 SOCIETE 4
    FR5 SOCIETE 5
    FR6 SOCIETE 6
    FR7 SOCIETE 7
    FR8 SOCIETE 8
    FR9 SOCIETE 9
    FR10 SOCIETE 10
    FR11 SOCIETE 11
    This is a sample description of my probleme because the real case is on multiple partition tables with million rows, but the problem is the same with this sample.
    My question is why it doesn't work ? Could anybody help me ?
    Thanks In advance.
    Loic

    Yes but you did not show where you want the parametersOK this is my Original Query :
    CREATE OR REPLACE PROCEDURE "PMU"."PROC_TEST_PMU_C035" (part_arrete in integer, part_session in integer)AS
    lv_p_arrete integer := part_arrete;
    lv_p_session integer := part_session;
    lv_stmt varchar2(31000);
    BEGIN
    lv_stmt := 'CREATE OR REPLACE MATERIALIZED VIEW PMU.TEST_PMU_C035 ';
    lv_stmt := lv_stmt || ' TABLESPACE PMU_8M_DATA ';
    lv_stmt := lv_stmt || ' BUILD IMMEDIATE ';
    lv_stmt := lv_stmt || ' REFRESH COMPLETE AS ';
    lv_stmt := lv_stmt || ' select CD_SOCIETE, MONTANT, MOIS, TYPEDET, LIEUCONS, DETPEA, PERSPHYS, SECTDET, PAYSDET, ZONEDET, CSPDET, AGEDET, TRMONT, NATINSFI, MATURITE, MONNAIE, DEVISEISO, SECTEMT, PAYSEMT, ZONEEMT, ENCRSDEB, NBCPTIT, TYPEFLUX, CONTRAT, CODISIN, LIBELTIT, SEUILDET, PAYSCTP, NBTIT, SEUILA1, SEUILA2, SEUILM1, SEUILM2, SEUILB1, SEUILB2, SEUILQ1, SEUILQ2, TXEVOL, NBCPTITPEA, NBCPTITPPP, ';
    lv_stmt := lv_stmt || ' NO_PCI || ''-'' || SECTDET || ''-'' || ZONEDET || ''-'' || MONNAIE || ''-'' || SECTEMT || ''-'' || DETPEA || ''-'' || PERSPHYS || ''-'' || (CASE WHEN TYPEDET IN (''DCL'', ''DCG'') THEN ''DCL'' ';
    lv_stmt := lv_stmt || ' ELSE NVL(TYPEDET,'''') ';
    lv_stmt := lv_stmt || ' END ) || ''-'' || (CASE WHEN NATINSFI in (''OBL'', ''EMT'', ''BTR'', ''CDD'', ''CDE'', ''CPP'', ''BTS'', ''MIB'') THEN ''OBL'' ';
    lv_stmt := lv_stmt || ' ELSE NVL(NATINSFI,'''') ';
    lv_stmt := lv_stmt || ' END) || ''-'' ||(CASE WHEN MATURITE IN (''A0'', ''A1'') THEN ''AC'' ELSE NVL(MATURITE,'''') END) || ''-'' ||(CASE WHEN PAYSEMT IN (''FR'',''MC'') THEN ''F1'' ';
    lv_stmt := lv_stmt || ' WHEN PAYSEMT IN (''DE'',''AT'',''BE'',''ES'',''FI'',''GR'',''IE'',''IT'',''LU'',''NL'',''PT'',''SI'', ''4F'') THEN ''ZE'' ';
    lv_stmt := lv_stmt || ' WHEN PAYSEMT IN (''BG'',''CY'',''DK'',''EE'',''HU'',''LV'',''LT'',''MT'',''PL'',''RO'',''GB'',''SK'',''SE'',''CZ'', ''4C'', ''4D'', ''4H'', ''4E'', ''4Z'', ''JE'') THEN ''ZU'' ';
    lv_stmt := lv_stmt || ' ELSE ''ZR''';
    lv_stmt := lv_stmt || ' END ) AS CLE';
    lv_stmt := lv_stmt || ' from PMU_ESLD_ESTD partition(PMU_M13_S14) e ,';
    lv_stmt := lv_stmt || ' PMU_ESLD_ESTD_SPPRO partition(PMU_M13_S14) a';
    lv_stmt := lv_stmt || ' where e.PART_ARRETE = '||lv_p_arrete ;
    lv_stmt := lv_stmt || ' AND e.PART_ENV = ''BCE''' ;
    lv_stmt := lv_stmt || ' AND e.PART_SESSION = '||lv_p_session ;
    lv_stmt := lv_stmt || ' and e.ID = a.ID_ESTD ';
    lv_stmt := lv_stmt || ' and e.CD_STATUT = ''VE'' ' ;
    lv_stmt := lv_stmt || ' and e.TYP_MONTANT = ''33'' ; ' ;
    execute immediate lv_stmt;
    END;
    Thanks

  • NULL and dynamic SQL

    If table testrh2 has the following columns and data
    col1 --> NULL
    col2 --> 2
    and table testrh has the following columsn and data
    col1 --> NULL
    How could I write a dynamic SQL statement to join on the nulls? I've written the following block as a starting point.
    declare
    cursor c1 is select col1 from isis.testrh;
    lval varchar2(1000);
    lval2 varchar2(1000);
    begin
    for r1 in c1 loop
    lval := 'select col2 from isis.testrh2 where col1 = '||r1.col1;
    execute immediate lval into lval2;
    dbms_output.put_line(lval2);
    end loop;
    end;

    You can't compare null values with '=' in Oracle SQL.
    Null can only be compared with <column> is null .
    You can see it when you try these two queries:
    select * from dual where null is null;  -- you will see one row
    select * from dual where null=null;  -- you will see no rowsThat's why you have to write something like
    (<column1>=<column1>   or   (<column1> is null and <column2> is null))This should also work with null:
    decode(<column1>,<column2>,1,0)=1By the way, why do you use dynamic sql?
    lval := 'select col2 from isis.testrh2 where col1 = '||r1.col1;
    I think you could replace your two lines ( lval:= ... AND execute immediate) by this:
    begin
      select col2
      into lval
      from isis.testrh2
      where decode(col1,r1.col1,1,0)=1;
      dbms_output.put_line('lval='||lval);
    exception
    when no_data_found then
      dbms_output.put_line('no data found'); -- or whatever you want
    end;Edited by: hartmutm on 02.10.2010 23:54

  • ORA-01008 with ref cursor and dynamic sql

    When I run the follwing procedure:
    variable x refcursor
    set autoprint on
    begin
      Crosstab.pivot(p_max_cols => 4,
       p_query => 'select job, count(*) cnt, deptno, row_number() over (partition by job order by deptno) rn from scott.emp group by job, deptno',
       p_anchor => Crosstab.array('JOB'),
       p_pivot  => Crosstab.array('DEPTNO', 'CNT'),
       p_cursor => :x );
    end;I get the following error:
    ^----------------
    Statement Ignored
    set autoprint on
    begin
    adsmgr.Crosstab.pivot(p_max_cols => 4,
    p_query => 'select job, count(*) cnt, deptno, row_number() over (partition by
    p_anchor => adsmgr.Crosstab.array('JOB'),
    p_pivot => adsmgr.Crosstab.array('DEPTNO', 'CNT'),
    p_cursor => :x );
    end;
    ORA-01008: not all variables bound
    I am running this on a stored procedure as follows:
    create or replace package Crosstab
    as
        type refcursor is ref cursor;
        type array is table of varchar2(30);
        procedure pivot( p_max_cols       in number   default null,
                         p_max_cols_query in varchar2 default null,
                         p_query          in varchar2,
                         p_anchor         in array,
                         p_pivot          in array,
                         p_cursor in out refcursor );
    end;
    create or replace package body Crosstab
    as
    procedure pivot( p_max_cols          in number   default null,
                     p_max_cols_query in varchar2 default null,
                     p_query          in varchar2,
                     p_anchor         in array,
                     p_pivot          in array,
                     p_cursor in out refcursor )
    as
        l_max_cols number;
        l_query    long;
        l_cnames   array;
    begin
        -- figure out the number of columns we must support
        -- we either KNOW this or we have a query that can tell us
        if ( p_max_cols is not null )
        then
            l_max_cols := p_max_cols;
        elsif ( p_max_cols_query is not null )
        then
            execute immediate p_max_cols_query into l_max_cols;
        else
            RAISE_APPLICATION_ERROR(-20001, 'Cannot figure out max cols');
        end if;
        -- Now, construct the query that can answer the question for us...
        -- start with the C1, C2, ... CX columns:
        l_query := 'select ';
        for i in 1 .. p_anchor.count
        loop
            l_query := l_query || p_anchor(i) || ',';
        end loop;
        -- Now add in the C{x+1}... CN columns to be pivoted:
        -- the format is "max(decode(rn,1,C{X+1},null)) cx+1_1"
        for i in 1 .. l_max_cols
        loop
            for j in 1 .. p_pivot.count
            loop
                l_query := l_query ||
                    'max(decode(rn,'||i||','||
                               p_pivot(j)||',null)) ' ||
                                p_pivot(j) || '_' || i || ',';
            end loop;
        end loop;
        -- Now just add in the original query
        l_query := rtrim(l_query,',')||' from ( '||p_query||') group by ';
        -- and then the group by columns...
        for i in 1 .. p_anchor.count
        loop
            l_query := l_query || p_anchor(i) || ',';
        end loop;
        l_query := rtrim(l_query,',');
        -- and return it
        execute immediate 'alter session set cursor_sharing=force';
        open p_cursor for l_query;
        execute immediate 'alter session set cursor_sharing=exact';
    end;
    end;
    /I can see from the error message that it is ignoring the x declaration, I assume it is because it does not recognise the type refcursor from the procedure.
    How do I get it to recognise this?
    Thank you in advance

    Thank you for your help
    This is the version of Oracle I am running, so this may have something to do with that.
    Oracle9i Enterprise Edition Release 9.2.0.8.0 - Production
    With the Partitioning, OLAP and Oracle Data Mining options
    JServer Release 9.2.0.8.0 - Production
    I found this on Ask Tom (http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:3027089372477)
    Hello, Tom.
    I have one bind variable in a dynamic SQL expression.
    When I open cursor for this sql, it gets me to ora-01008.
    Please consider:
    Connected to:
    Oracle8i Enterprise Edition Release 8.1.7.4.1 - Production
    JServer Release 8.1.7.4.1 - Production
    SQL> declare
      2    type cur is ref cursor;
      3    res cur;
      4  begin
      5    open res for
      6    'select * from (select * from dual where :p = 1) connect by 1 = 1'
      7    using 1;
      8  end;
      9  /
    declare
    ERROR at line 1:
    ORA-01008: not all variables bound
    ORA-06512: at line 5
    SQL> declare
      2    type cur is ref cursor;
      3    res cur;
      4  begin
      5    open res for
      6    'select * from (select * from dual where :p = 1) connect by 1 = 1'
      7    using 1, 2;
      8  end;
      9  /
    PL/SQL procedure successfully completed.
    And if I run the same thing on 10g -- all goes conversely. The first part runs ok, and the second
    part reports "ORA-01006: bind variable does not exist" (as it should be, I think). Remember, there
    is ONE bind variable in sql, not two. Is it a bug in 8i?
    What should we do to avoid this error running the same plsql program code on different Oracle
    versions?
    P.S. Thank you for your invaluable work on this site.
    Followup   June 9, 2005 - 6pm US/Eastern:
    what is the purpose of this query really?
    but it would appear to be a bug in 8i (since it should need but one).  You will have to work that
    via support. I changed the type to tarray to see if the reserved word was causing a problem.
    variable v_refcursor refcursor;
    set autoprint on;
    begin 
         crosstab.pivot (p_max_cols => 4,
                 p_query => 
                   'SELECT job, COUNT (*) cnt, deptno, ' || 
                   '       ROW_NUMBER () OVER ( ' || 
                   '          PARTITION BY job ' || 
                   '          ORDER BY deptno) rn ' || 
                   'FROM   emp ' ||
                   'GROUP BY job, deptno',
                   p_anchor => crosstab.tarray ('JOB'),
                   p_pivot => crosstab.tarray ('DEPTNO', 'CNT'),
                   p_cursor => :v_refcursor);
    end;
    /Was going to use this package as a stored procedure in forms but I not sure it's going to work now.

  • Performance between SQL Statement and Dynamic SQL

    Select emp_id
    into id_val
    from emp
    where emp_id = 100
    EXECUTE IMMEDIATE
    'Select '|| t_emp_id ||
    'from emp '
    'where emp_id = 100'
    into id_valWill there be more impact in performance while using Dynamic SQL?

    CP wrote:
    Will there be more impact in performance while using Dynamic SQL?All SQLs are parsed and executed as SQL cursors.
    The 2 SQLs (dynamic and static) results in the exact same SQL cursor. So both methods will use an identical cursor. There are therefore no performance differences ito of how fast that SQL cursor will be.
    If an identical SQL cursor is not found (a soft parse), the SQL engine needs to compile the SQL source code supplied, into a SQL cursor (a hard parse).
    Hard parsing burns a lot of CPU cycles. Soft parsing burns less CPU cycles and is therefore better. However, no parsing at all is the best.
    To explain: if the code creates a cursor (e.g. INSERT INTO tab VALUES( :1, :2, :3 ) for inserting data), it can do it as follows:
    while More Data Found loop
      parse INSERT cursor
      bind variables to INSERT cursor
      execute INSERT cursor
      close INSERT cursor
    end loopIf that INSERT cursor does not yet exists, it will be hard parsed and a cursor created. Each subsequent loop iteration will result in a soft parse.
    However, the code will be far more optimal as follows:
    parse INSERT cursor
    while More Data Found loop
      bind variables to INSERT cursor
      execute INSERT cursor
    end loop
    close INSERT cursorWith this approach the cursor is parsed (hard or soft), once only. The cursor handle is then used again and again. And when the application is done inserting data, the cursor handle is released.
    With dynamic SQL in PL/SQL, you cannot really follow the optimal approach - unless you use DBMS_SQL (a complex cursor interface). With static SQL, the PL/SQL's optimiser can kick in and it can optimise its access to the cursors your code create and minimise parsing all together.
    This is however not the only consideration when using dynamic SQL. Dynamic SQL makes coding a lot more complex. The SQL code can now only be checked at execution time and not at development time. There is the issue of creating shareable SQL cursors using bind variables. There is the risk of SQL injection. Etc.
    So dynamic SQL is seldom a good idea. And IMO, the vast majority of people that post problems here relating to dynamic SQL, are using dynamic SQL unnecessary. For no justified and logical reasons. Creating unstable code, insecure code and non-performing code.

  • DDL statements and dynamic  sql  in stored procedure

    I created a stored procedure to create and drop tables, using dynamic sql.
    When I try to do the inserts using dynamic sql, i.e
    v_string := 'INSERT statement';
    EXECUTE IMMEDIATE v_string;
    I get the following error message:
    ERROR at line 1:
    ORA-00942: table or view does not exist
    ORA-06512: at line 63
    Line 63 happens to be the line that the EXECUTE IMMEDIATE v_string; statement is in.
    I am able to describe the table that the inserts are being made into, so I know that the table exists.
    Any idea why I'm getting this error message would be appreciated.

    Yes I do and I have been able to create other tables using dynamic sql.
    The table that I am having problems with SELECTs data from another table to get its column values; within the SELECT statement, the CAST function is used:
    ie. CAST(CASE SUBSTR(CAST(E_MOD AS VARCHAR(7)),2,3)
    WHEN 'AAA' THEN 'A55'
    ELSE ............
    I get the following error message:
    ERROR at line 18: (this line starts the CAST statement)
    ORA-06550: line 18, column 13:
    PLS-00103: Encountered the symbol "AAA" when expecting one of the following:
    . ( * @ % & = - + ; < / > at in is mod not rem return
    returning <an exponent (**)> <> or != or ~= >= <= <> and or
    like between into using || bulk
    When I remove the quotes or add another single quote, the same error cascades to 'A55'.
    After doing the same for the next error, I get the error message below:
    ERROR at line 1: (this line has the EXECUTE IMMEDIATE statement)
    ORA-00936: missing expression
    ORA-06512: at line 6
    Any idea what the problem could be?
    Also is there another way to have DDL statements as stored procedures other than using dynamic sql or the DBMS_SQL package?

  • Execute immediate and "in" operator

    Hello!
    I want to pass varchar2 type argument to my procedure in format '1,2,3' where 1,2 and 3 are some IDs.
    And then, in procedure I write:
    stmt := 'select avg(PRICE) from ORDERS where ORDER_ID in (:Ids)';
    execute immediate stmt into APrice using ARGUMENT;
    I undersand, that this is incorrect, because where clause in executable query is
    "where ORDER_ID in ('1,2,3')" but not "where ORDER_ID in (1,2,3)".
    Is there any easy way how to solve such a problem?
    Maybe I should use other argument type?

    user10304317 wrote:
    I undersand, that this is incorrect, because where clause in executable query isIf you want to use a string you will have to concatenate it into dynamic sql:
    stmt := 'select avg(PRICE) from ORDERS where ORDER_ID in (' || ARGUMENT || ')';
    execute immediate stmt into APrice;However, it will produce as many sql in shared pool as you will have different ARGUMENT values and each of them will do a hard parse. Or you could use collection and then you do not need dynamic sql (unless select list and/or rest of where clause is dynamic):
    SQL> create or replace
      2    type num_tbl_type
      3      as
      4        table of number;
      5  /
    Type created.
    SQL> create or replace procedure p1(
      2                                 p_num_tbl num_tbl_type
      3                                )
      4    is
      5    begin
      6        for rec in (select empno,ename from emp where empno in (select * from table(p_num_tbl))) loop
      7          dbms_output.put_line(rpad(rec.empno,10) || rec.ename);
      8        end loop;
      9  end;
    10  /
    Procedure created.
    SQL> set serveroutput on
    SQL> exec p1(num_tbl_type(7566,7839,7902))
    7566      JONES
    7839      KING
    7902      FORD
    PL/SQL procedure successfully completed.
    SQL> SY.

  • Difficulties with execute immediate and 'in' clause

    Hello all,
    I have some SQL that will have to run dynamically, which I can get to work by building a long statement, then getting it hard-parsed
    example:
    sql_stmt VARCHAR2(256) :=
    'select distinct some_id from table1
    where lname = ''Smith''
    and fname in(''Joe'', ''Joey'', ''Joseph'')
    and ssn = 111223333';
    execute immediate sql_stmt into new_id_value;
    the above state executes fine and returns the desired result.
    HOWEVER, when I try to use bind variables (this statement will be called several million times), I get a no rows returned error.
    I use bind variables as follows:
    sql_stmt VARCHAR2(256);
    vlname VARCHAR2(50) := 'Smith';
    vssn NUMBER := 111223333;
    vfname VARCHAR2(100) := '''Joe'', ''Joey'', ''Joseph''';
    sql_stmt :=
    'select distinct some_id from table1
    where lname = :vlname
    and fname in(:vfname)
    and ssn = :vssn;
    execute immediate sql_stmt into new_id_value
    using vlname, vfname, vssn;
    I know the issue involves the 'in' clause because I've substituted hardcoded values in and it has worked.
    any suggestions?

    Well maybe its all a little confusing, does an end to end demo make it any clearer Mr Bidness?
    SQL> create or replace type tabstr_t as table of varchar2(4000)
      2  /
    Type created.
    SQL> create or replace function tabstr (
      2      p_str in varchar2,
      3      p_sep in varchar2 default ','
      4      )
      5  return tabstr_t
      6  is
      7      l_str long := p_str || p_sep;
      8      l_tabstr tabstr_t := tabstr_t();
      9  begin
    10      while l_str is not null loop
    11          l_tabstr.extend(1);
    12          l_tabstr(l_tabstr.count) := rtrim(substr(
    13                  l_str,1,instr(l_str,p_sep)),p_sep);
    14          l_str := substr(l_str,instr(l_str,p_sep)+1);
    15      end loop;
    16      return l_tabstr;
    17  end;
    18  /
    Function created.
    SQL> var s varchar2(100)
    SQL> exec :s := 'king,turner,ward'
    PL/SQL procedure successfully completed.
    SQL> select ename, sal from emp
      2  where ename in (
      3    select upper(column_value) from
      4    table(cast(tabstr(:s) as tabstr_t))
      5    );
    ENAME             SAL
    KING             5000
    TURNER           1500
    WARD             1250
    SQL> exec :s := 'jones,blake,clark'
    PL/SQL procedure successfully completed.
    SQL> /
    ENAME             SAL
    BLAKE            2850
    CLARK            2450
    JONES            2975

  • Strange behavior when searching a phrase using reg exp and dynamic sql

    Hi,
    I have a strange issue while using dynamic sql for an apex page. I have a requirement to search a string in the database column which is entered by user on a page item. The search process should search the whole phrase only.
    I have a query generated dynamically in the back end and use it in a cursor in the stored procedure
      SELECT t.group_cn , t.group_desc, t.group_type, t.partner_organization_id, t.partner_organization
      FROM vr_idm_group t WHERE regexp_like(t.group_desc,'(^|\W)HR Selection & Assignment(\W|$)', 'i')The pl sql code with the dynamic sql statements are below.
       IF p_search_process NOT in ('PARTNER') THEN
          OPEN v_cursor FOR v_sql;
       ELSE
          OPEN v_cursor FOR v_sql USING p_search_id;
       END IF;
       LOOP
          FETCH v_cursor INTo v_obj.group_cn, v_obj.group_desc, v_obj.group_type, v_obj.partner_organization_id,
             v_obj.partner_organization, v_obj.match_count;
          EXIT WHEN v_cursor%NOTFOUND ;
          v_search_array.extend;
          v_search_array(v_search_array.last) := v_obj;
          dbms_output.put_line(v_sql);
       END LOOP;The search works fine if the search string does not contain any special character like &,- etc.
    However, if the search string contains any special character, it does not return any thing. This strange issue happens only if I call the procedure from the apex page and the search string contains a special character. (please note that the procedure works fine even from apex if the string does not have a special character). When I debugged this, found that, the cursor does not fetch any rows (it is supposed to fetch two rows) for unknown reason. When I run the query separately, it returns the two rows (in which the column group_desc contains the search string "HR Selection & Assignment") as desired. Also, when I test the procedure in the back end (PLSQL developer), it works fine.
    Any idea, what is causing this strange behaviour?
    Advance thanks.
    Regards,
    Natarajan

    i don't see anything about a dataProvider.  you're assigning a source for a scrollpane.  scrollpane's don't have a dataProvider property.
    anyway, other than arrayRun always being false when that last if-statement executes, what's the problem?  doesn't that movieclip display when that 2nd branch of the last if-statement executes (assuming instance is defined correctly etc)?

  • Bind variables and Dynamic sql

    I have this function which works only when i'm not passing bind variables. The moment i add bind variables it is not able to execute the function.
    Oracle Db Version: 8.1
    Thanks
    Source Code
    FUNCTION TestFunction( In_Test_id in Number,
    In_Asof in Date )
    Return ScoreType
    IS
    LvScore ABC.LV_SCORE.SCORE%TYPE;
    DVScore ABC.LV_SCORE.SCORE%TYPE;
    Begin
    EXECUTE IMMEDIATE
    'SELECT SCORE,DVSCORE
    FROM
    SELECT SCORE,DVSCORE
    DENSE_RANK() OVER (PARTITION BY TEST_ID ORDER BY ASOF_DT DESC) AS score_RANK
    FROM ABC.LV_SCORE
    WHERE TEST_ID = :x
    AND ASOF_DT <= :y
    ) WHERE score_RANK = 1'
    INTO LvScore,DVScore
    USING In_tEST_ID,In_Asof;
    Return ScoreType( LvScore,
    DVScore);
    End;

    It just keeps on executing for sometime and then disconnects itself from database What was the indication that told you that it disconnected? Was there a visible indication of this disconnect?
    Did you get ORA-03113?
    ===========================================
    ORA-03113: end-of-file on communication channel
    Cause: The connection between Client and Server process was broken.
    Action: There was a communication error that requires further investigation. First, check for network problems and review the SQL*Net setup. Also, look in the alert.log file for any errors. Finally, test to see whether the server process is dead and whether a trace file was generated at failure time.

  • BCP and dynamic SQL

    Hello All,
    Been looking into this for a couple of days, and I keep hitting brick walls, so I'm hoping someone can offer me a bit of inspiration. What I'm trying to do is write a stored procedure that lets the user specify a list of tables, and an output directory, and the SP creates a series of BCP statements that export these tables to comma delimited files.
    This wouldn't be too hard, but I need to output the field headings in the first row of the table (and use quotes as text qualifiers). I'm doing this by looping round sys.columns, pulling out all the fieldnames, creating two select statements, and UNION ALL-ing them together. e.g.......
    select 'FIELD1','FIELD2','FIELD3','FIELD4'
    union all
    select field1,field2,field3,field4 from tablename
    It all works fine until you try it on a table with a lot of columns. Although you can build a big SQL statement in an NVARCHAR(MAX), BCP only appears to read the first 4000 characters of it, so it fails.
    To get round this, I've moved all of the code that builds the big SQL statement to its own stored procedure (i.e. you pass the tablename, and it returns the table with the field names in the first row). Then, I can just call this new SP in my BCP statement, with a couple of parameters. 
    The problem I'm getting is BCP is complaining saying '[Microsoft][SQL Native Client]BCP host-files must contain at least one column'.  I'm setting no count off, and there are no print statements, so I'm assuming this is because the data is getting returned via an exec sp_executesq (although this is a guess). I can't think of a way round this though, as the SQL need to be dynamic.
    alter PROCEDURE [dbo].[sp_QBMultiFileExportGetData]
    @tablename varchar(100),
    @dbname varchar(100)
    AS
    BEGIN
    declare @Execstring as nvarchar(MAX)
    declare @currentfieldname as varchar(100)
    declare @selectlist as varchar(8000)
    declare @fieldnamelist as varchar(8000)
    declare @colnames table
    columnname varchar(100)
    begin
    set nocount on
    set @execstring='select COLUMN_NAME '+
    'from ' + @dbname + '.INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = ''' + @tablename + ''''
    insert into @colnames(columnname)
    exec sp_executesql @execstring
    set @selectlist=''
    set @fieldnamelist=''
    --Loop through fieldnames, and build two strings
    --One for outputting fieldnames and one for selecting the actual data
    while exists(select * from @colnames)
    begin
    select top 1 @currentfieldname=columnname from @colnames
    set @selectlist=@selectlist + 'quotename(['+ @currentfieldname + '],char(34)),'
    set @fieldnamelist=@fieldnamelist + '''' + @currentfieldname + ''' [' +@currentfieldname + '],'
    delete from @colnames where columnname=@currentfieldname
    end
    --remove last quote
    set @selectlist=substring(@selectlist,1,len(@selectlist)-1)
    set @fieldnamelist=substring(@fieldnamelist,1,len(@fieldnamelist)-1)
    --Built string to execute, with fieldnames, and select fields
    set @execstring='select ' + @fieldnamelist  + ' union all select ' + @selectlist + ' from ' + @dbname + '..'  + @tablename
    return exec sp_executesql @execstring
    end
    END
    this returns exactly what I want, but when I try to use it in a BCP statement, I get the error....
    i.e.
    EXEC master..xp_cmdshell 'bcp "exec QCDev.dbo.sp_QBMultiFileExportGetData ''tablename'',''dbname''" queryout C:\\outputfile.txt -T -t","'
    Error = [Microsoft][SQL Native Client]BCP host-files must contain at least one column
    Anyone ever tried this before?

    Hi Guys,
    Thanks for the suggestions. I had been trying to avoid temp tables (don't really like them), but I think eventually, they were the only way to go. Unfortunately, this opened a whole can of scoping worms, and after a couple of hours, its all given me a right headache. However, the good news is I've finally got it working as I wanted.
    I was finding I was having issues using temp tables, as the tables being used were dynamic, so I would have to create them in a dynamic SQL string, and they weren't propagating upwards from child to parent. I seemed to be getting the same problem using global temporary tables too, although I'm not sure why, as they should have worked They seemed to be out of scope by the time the SP that was calling my sp_QBMultiFileExportGetData tried to output the data. This might possibly have been because BCP wasn't seeing the same scope, but I've not tested it fully (and its very possible I was making a mistake).
    The solution was to abandon sp_QBMultiFileExportGetData, and merge the code back into the calling script. However, rather than trying to pass an enormous SQL string to bcp, running it separately with sp_executesql, and dumping the results in a global temp table. Then let bcp just call a 'select * from temptable', to avoid the select statement getting too long. Its not the most elegant solution, but it seems to work fine.
    ALTER PROCEDURE [dbo].[sp_QBMultiFileExport]
    -- Add the parameters for the stored procedure here
    @tablenames varchar(1000), --list of tables to be exported
    @outputpath varchar(1000), --output path ***AS SEEN BY THE SERVER, NOT THE CLIENT***
    @servername varchar(100), --Server where data resides
    @dbname varchar(100), --database name
    @delimiter varchar(1) --output delimiter
    AS
    BEGIN
    declare @Execstring as nvarchar(max)
    declare @currenttable as varchar(100)
    declare @colnames table
    columnname varchar(100)
    declare @currentfieldname as varchar(100)
    declare @selectlist as varchar(max)
    declare @fieldnamelist as varchar(max)
    --Get rid of CRLFs in the tablenames parameter
    set @tablenames=replace(@tablenames,char(10),'')
    set @tablenames=replace(@tablenames,char(13),'')
    --add extra comma to the end of the list (needed later for consistency)
    set @tablenames=@tablenames+','
    --Get first table in the list
    set @currenttable=substring(@tablenames,1,charindex(',',@tablenames)-1)
    while @tablenames<>''
    begin
    --Get a list of fieldnames from syscols
    insert into @colnames(columnname)
    select COLUMN_NAME
    from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @currenttable
    set @selectlist=''
    set @fieldnamelist=''
    while exists(select * from @colnames)
    begin
    --get first column name
    select top 1 @currentfieldname=columnname from @colnames
    --add to select statement lists
    set @selectlist=@selectlist + 'quotename(['+ @currentfieldname + '],char(34)),'
    set @fieldnamelist=@fieldnamelist + '''' + @currentfieldname + ''' [' +@currentfieldname + '],'
    --remove column from temptable
    delete from @colnames where columnname=@currentfieldname
    end
    --remove last quote from field lists
    set @selectlist=substring(@selectlist,1,len(@selectlist)-1)
    set @fieldnamelist=substring(@fieldnamelist,1,len(@fieldnamelist)-1)
    --check for temp table, and drop if necessary
    IF object_id('tempdb..##MultiFileExportTempTable') IS NOT NULL
    BEGIN
    DROP TABLE ##MultiFileExportTempTable
    END
    --Build list of fieldnames, and select list, unioned together
    --and put the results in temptable
    set @execstring='select ' + @fieldnamelist  + ' into ##MultiFileExportTempTable union all select ' + @selectlist + ' from ' + @dbname + '..'  + @currenttable
    exec sp_executesql @execstring
    --get BCP to pull data back from ##temptable, and dump in file
    set @execstring='EXEC master..xp_cmdshell ''bcp "select * from ##MultiFileExportTempTable" queryout ' + @outputpath + '\' + @currenttable + '.txt' + ' -c -T -t"' + @delimiter + '"'''
    exec sp_executesql @execstring
    --drop tablename from list
    set @tablenames=replace(@tablenames,@currenttable + ',','')
    --if tablenames list is not empty, get the next one
    if @tablenames<>''
    set @currenttable=substring(@tablenames,1,charindex(',',@tablenames)-1)
    else
    set @currenttable=''
    end
    IF object_id('tempdb..##MultiFileExportTempTable') IS NOT NULL
    BEGIN
    DROP TABLE ##MultiFileExportTempTable
    END
    END
    So, you call this with...
    exec dbo.[sp_QBMultiFileExport] 'table1,table2,table3',filepath,servername,dbname,delimiter
    ...and it creates delimited files called table1.txt, table2.txt and table3.txt in the specified folder, with field headings and text qualifiers.
    Many thanks for all your suggestions

Maybe you are looking for

  • Creating Dynamic Column Names at Runtime

    I have a dynamic query that I'm running under Portal. I would like to assign column headings based on the query results. Example: Select a.x "a.name_x", a.y "a.name_y", a.z "a.name_z" from a where a.q = "user input" I know the above example will not

  • IPod touch 4th generation connection problems

    My iPod touch indicates that it is connected to wifi (a connection that I frequently used in the past, and use for all my other deivces), and I even full wifi strength (three 'bars'), but I cannot use various apps that connect to the Internet or conn

  • Details not appearing in the dropdown list in the filter window

    Dear All,    I have come accross a unique problem. I have made a user defined query. Now there is an item code column. I want to filter the item codes in the generated query. But all the items are not appearing in the filter window> item field> dropd

  • Export data to anothe PDF form

    Hello all, I have a research company that needs to keep track of all patients we see by entering their initials, date of visit, date of birth and some other simple data in a cumulative log (a PDF form). When the patient comes to our site we gather th

  • Cannot download apps in app store

    every time I try to download an app, itunes 9.1.0.8 hangs and I have to stop force quit the app. running windows vista ultimate fully updated also any solutions? thanks, marianne