Execute immediate ignoring hints

Hi
I'm looking for help about an unexpected behavior in oracle. I have a query that it is executed by a stored procedure, and this query has some hints to improve its performance. When I execute the procedure with sqlplus or any other tool, using "exec myprocedure;", the process took between 30 and 40 minutes to complete. But if I call this procedure inside another procedure with execute immediate command, it took more than 5 hours to complete.
The procedure code is
execute immediate 'begin '||proc||'; end;';
proc is a variable that contain the procedure name to run
It seems that oracle are ignoring my hints when it is executed by execute immediate command. In all tests that I've done I used the same user to connect.
The version of oracle is 9.2.0
Tks for any help

> Why would you do this?
Presumably he has a variable like "v_which_procedure" which could have the values 'RAISE_PAY()' or 'FIRE_ALL_EMPLOYEES()', and some logic that determines which to use.
I would agree though that in general it would be better to structure things so that you are not in the position of slotting the name of a procedure dynamically into an EXECUTE IMMEDIATE call.
I don't see how SQL inside a procedure would know that the procedure itself was called dynamically, so the fact that it seems to be performing differently is a bit of a mystery. I would want to be absolutely sure that that was actually what it was doing.

Similar Messages

  • Can't create a sequence within a pl/sql block with execute immediate.

    Hi All. I created a user and granted it the 'create sequence' privilege though a role. In a pl/sql block I try to create a sequence using 'execute immediate' but get a 1031-insufficient privileges error. If I grant create sequence directly to the user, the pl/sql block completes successfully. Can anyone explain this behavior? We're running 11.2 Enterprise Editon.
    Thanks,
    Mark

    In a definer's rights stored procedure (the default), you only have access to privileges that have been granted directly, not via a role.
    There are two basic reasons for that. First, roles can be enabled or disabled, default and non-default, password-protected, etc. so the set of roles a particular user actually has is session-specific. Oracle needs to know at compile time what privileges the owner of the procedure has. The only way to do that (without deferring the privilege check) is to ignore privileges granted through roles.
    Second, since 99% of privilege management DBAs do involves granting and revoking roles, it's helpful that changing role privileges will never cause objects to be marked invalid and recompiled which can have side-effects on applications. DBAs only need to worry about causing problems on those rare cases where they are granting or revoking direct privileges to users.
    You can create an invoker's rights stored procedure by adding the clause (AUTHID CURRENT_USER). That defer's the security check to run-time but allows the procedure to see privileges granted through roles in the current session. But that means that the caller of the procedure would need to have the CREATE SEQUENCE privilege through the role, not the owner of the procedure.
    And just to make the point, dynamic object creation in PL/SQL is almost always a red flag that there is something problematic in your design. If you are creating sequences dynamically, that means that you'd have to refer to them dynamically throughout your code which means that your inserts would need to use dynamic SQL. That's not a particularly easy or safe way to develop code.
    Justin

  • How to use using clause in execute immediate statement??

    Hi ALL,
    Can u help me ....
    This is the code which I have written...
    declare
    type rec_typ is table of forall_test%rowtype;
    v_rectype rec_typ:=rec_typ();
    begin
    --poputating records
    for i in 1..10000 loop
    v_rectype.extend;
    v_rectype(v_rectype.last).id:=i;
    v_rectype(v_rectype.last).code:=to_char(i);
    v_rectype(v_rectype.last).description:='Description :'||to_char(i);
    end loop;
    execute immediate 'truncate table forall_test';
    forall i in v_rectype.first..v_rectype.last
    execute immediate 'insert into forall_test values :1' using v_rectype(i);
    commit;
    end;
    But I am getting this ERROR....
    execute immediate 'insert into forall_test values :1' using v_rectype(i);
    ERROR at line 14:
    ORA-06550: line 14, column 61:
    PLS-00457: expressions have to be of SQL types
    ORA-06550: line 14, column 1:
    PL/SQL: Statement ignored
    Thanks & Regards,
    T.Halder

    Thatmeans using statement cannot be a non sql type.True: You need an sql type for this:
    e.g. with
    create or replace type emp_typ
    as
       object (empno number (4),
               ename varchar2 (10 byte),
               job varchar2 (9 byte),
               mgr number (4),
               hiredate date,
               sal number (7, 2),
               comm number (7, 2),
               deptno number (2))
    create or replace type emp_tab as table of emp_typ
    /you can do
    --- an empty test table
    SQL> create table emp2
    as
       select *
       from emp
       where 1 = 2
    Table created.
    SQL> declare
       emp2_tab       emp_tab;
    begin
      /* fill the collection */
       select emp_typ (empno,
                       ename,
                       job,
                       mgr,
                       hiredate,
                       sal,
                       comm,
                       deptno)
       bulk collect into emp2_tab
       from emp
       where empno like '77%';
      --  forall loop
       forall c in 1 .. emp2_tab.count
          execute immediate 'begin
                               insert into emp2 select * from table(cast(emp_tab(:1) as emp_tab)) t;
                               update emp2 set sal = null where empno = (:1).empno and empno = 7788;
                             end;' using emp2_tab (c);
    end;
    PL/SQL procedure successfully completed.
    SQL> select empno, ename, sal from emp2
         EMPNO ENAME             SAL
          7782 CLARK            2450
          7788 SCOTT               
    2 rows selected.

  • Pass Pl/sql table into USING clause in EXECUTE IMMEDIATE statment

    Getting error when I try to pass the PL/SQL table into USING clause in EXECUTE IMMEDIATE statment:
    Declare
    result NUMBER;
    TYPE values_tab IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
    lv_tab values_tab;
    lv_exp varchar2(300);
    lv_exec varchar2(300);
    BEGIN
    lv_tab(1) := 5;
    lv_tab(2) := 48;
    lv_tab(3) := 7;
    lv_tab(4) := 6;
    lv_exp := ':b1+:b2+(:b3*:b4)';
    lv_exec := 'SELECT '||lv_exp ||' FROM DUAL';
    EXECUTE IMMEDIATE
    lv_exec
    INTO
    result
    USING
    lv_tab;
    DBMS_OUTPUT.PUT_LINE(result);
    END;
    Error at line 1
    ORA-06550: line 20, column 12:
    PLS-00457: expressions have to be of SQL types
    ORA-06550: line 15, column 8:
    PL/SQL: Statement ignored
    I am trying to evaluate the expression ":b1+:b2+(:b3*:b4)" which is stored in table. This table has different expressions (around 300 expressions). I want to use the bind variables in expression because each expression evaluated thousand of time may be more in some case. If I don't use bind variable then it fill shared pool.
    Is there any way I can pass the USING (IN) parameters dynamically instead of writing "USING lv_tab(1), lv_tab(2), lv_tab(3), lv_tab(4)"? As number of input parameters change depend on the expression in the table.
    If not possible please suggest any other ideas/approches
    Please help..
    Edited by: satnam on Jun 11, 2009 11:50 AM

    Well, you keep changing reqs faster I can keep up. Anyway, assuming N-th bind variable (left-to-right) corresponds to collection N-th element:
    Declare
        result NUMBER;
        lv_tab values_tab := values_tab();
        lv_exp varchar2(300);
        lv_exec varchar2(300);
        lv_i number := 0;
    BEGIN
        lv_tab.extend(4);
        lv_tab(1) := 5;
        lv_tab(2) := 48;
        lv_tab(3) := 7;
        lv_tab(4) := 6;
        lv_exp := ':5000135+:5403456+(:5900111*:5200456)';
        lv_exec := lv_exp;
        While regexp_like(lv_exec,':\d+') loop
          lv_i := lv_i + 1;
          lv_exec := REGEXP_REPLACE(lv_exec,':\d+',':b(' || lv_i || ')',1,1);
        end loop;
        lv_exec := 'BEGIN :a := ' || lv_exec || '; END;';
    DBMS_OUTPUT.PUT_LINE(lv_exec);
    EXECUTE IMMEDIATE lv_exec USING OUT result,IN lv_tab;
    DBMS_OUTPUT.PUT_LINE(result);
    END;
    BEGIN :a := :b(1)+:b(2)+(:b(3)*:b(4)); END;
    95
    PL/SQL procedure successfully completed.
    SQL> SY.

  • Execute immediate 'alter session set current_schema = ' failed in PL/SQL

    Hi
    I am trying to run
    EXECUTE IMMEDIATE 'ALTER SESSION SET CURRENT_SCHEMA = TEST ' ;
    in a pl/sql block but it is failing.Can anyone update me on this.
    CREATE OR REPLACE PROCEDURE test3
    IS
    A_COUNT NUMBER(15);
    BEGIN
    EXECUTE IMMEDIATE 'ALTER SESSION SET CURRENT_SCHEMA = TEST ' ;
    SELECT COUNT(*) INTO A_COUNT FROM (
    select id from solutions );
    END;
    /

    The user who owns the procedure needs to be granted direct select rights on table test.solutions (not via a role). Still will not help. Look what OP is trying to do. In a stored procedure owned by some user (other than TEST) OP is trying to reference user TEST owned table solution without prefixing it with owner. Something like:
    SQL> create table u1.test_tbl(x number);
    Table created.
    SQL> select * from test_tbl;
    select * from test_tbl
    ERROR at line 1:
    ORA-00942: table or view does not exist
    SQL> alter session set current_schema = U1;
    Session altered.
    SQL> select * from test_tbl;
    no rows selected
    SQL> However, OP tries to do it in a SP using dynamic SQL to change current schema to test. Such change will occur when SP will be executed, not when is it compiled. At compile time we are still under SP owner's schema and therefore select from solutions implies table solutions owned by SP owner, not by TEST. The only way to make SP compile and work OK is to select from solutions also dynamically:
    SQL> select sys_context('userenv','current_schema') from dual
      2  /
    SYS_CONTEXT('USERENV','CURRENT_SCHEMA')
    SCOTT
    SQL> CREATE OR REPLACE PROCEDURE test3
      2  IS
      3  A_COUNT NUMBER(15);
      4  BEGIN
      5  EXECUTE IMMEDIATE 'ALTER SESSION SET CURRENT_SCHEMA = U1' ;
      6  SELECT COUNT(*) INTO A_COUNT FROM (
      7  select x from test_tbl );
      8  END;
      9  /
    Warning: Procedure created with compilation errors.
    SQL> sho err
    Errors for PROCEDURE TEST3:
    LINE/COL ERROR
    6/1      PL/SQL: SQL Statement ignored
    7/15     PL/SQL: ORA-00942: table or view does not exist
    SQL> set serveroutput on
    SQL> CREATE OR REPLACE PROCEDURE test3
      2  IS
      3  A_COUNT NUMBER(15);
      4  c sys_refcursor;
      5  BEGIN
      6  EXECUTE IMMEDIATE 'ALTER SESSION SET CURRENT_SCHEMA = U1' ;
      7  OPEN C FOR 'SELECT COUNT(*) FROM (select x from test_tbl )';
      8  FETCH c INTO A_COUNT;
      9  dbms_output.put_line(a_count);
    10  CLOSE c;
    11  END;
    12  /
    Procedure created.
    SQL> insert into u1.test_tbl select rownum from emp;
    14 rows created.
    SQL> exec test3
    14
    PL/SQL procedure successfully completed.
    SQL> Obviously, as you noted SP owner must have directly granted select on test3.solutions.
    SY.

  • Can I issue this command in PL/SQL: EXECUTE IMMEDIATE '@filename.sql';

    can I issue this command in PL/SQL: EXECUTE IMMEDIATE '@filename.sql';

    Hi,
    Rather the opening a new process (sqlplus), a new connection (need password) etc... I would rather read and execute the file in pl/sql.
    I do not know if someone wrote it already, but here is a quick and dirty code for doing that with UTL_FILE.GET_LINE
    Here, I am only processing some DML statements and no SELECT statements. Correct it as you like !
    CREATE OR REPLACE PROCEDURE run_script ( dir_name IN VARCHAR2,file_name IN VARCHAR2)
    IS
    vSFile UTL_FILE.FILE_TYPE;
    vCmd VARCHAR2(200);
    vNewLine VARCHAR2(200);
    BEGIN
        vSFile := UTL_FILE.FOPEN(dir_name, file_name,'r');
        vCmd := NULL;
        IF UTL_FILE.IS_OPEN(vSFile) THEN
        LOOP
            BEGIN
                UTL_FILE.GET_LINE(vSFile, vNewLine);
                if (vCmd is null) THEN
                    if (upper(vNewLine) like 'INSERT%' or upper(vNewLine) like 'UPDATE%' or upper(vNewLine) like 'DELETE%') THEN
                        if (vNewLine like '%;') THEN
                            /* we have a single line command, execute it now */
                            dbms_output.put_line(substr(vNewLine,1, length(vNewLine)-1));
                            execute immediate substr(vNewLine,1, length(vNewLine)-1);
                        else
                            /* we have a command over multiple line, set vCmd */
                            vCmd := vNewLine;
                        end if;
                    else
                        /* ignore the rest like spool, prompt, accept, errors, host, @, ... */
                        null;
                    end if;
                else
                    if (vNewLine like '%;') THEN
                        /* we have a the last line of the command, execute it now */
                        vCmd := vCmd || ' ' || substr(vNewLine,1, length(vNewLine)-1);
                        dbms_output.put_line(vCmd);
                        execute immediate vCmd;
                        vCmd := null;
                    else
                        /* keep concatenating to vCmd */
                        vCmd := vCmd ||' '|| vNewLine;
                    end if;
                end if;
            EXCEPTION
                WHEN NO_DATA_FOUND THEN
                    EXIT;
                END;
        END LOOP;
        COMMIT;
        END IF;
        UTL_FILE.FCLOSE(vSFile);
    EXCEPTION
        WHEN utl_file.invalid_path THEN
            RAISE_APPLICATION_ERROR (-20052, 'Invalid File Location');
        WHEN utl_file.read_error THEN
            RAISE_APPLICATION_ERROR (-20055, 'Read Error');
        WHEN others THEN
            RAISE_APPLICATION_ERROR (-20099, 'Unknown Error');
    END run_script;
    set serverout on
    create directory scriptdir as '/home/oracle';
    grant read,write on directory to scott;
    exec run_script('SCRIPTDIR', 'test.sql')

  • Creating cursor using Execute immediate

    I am trying to create one cursor using a for loop, but I am not able to do so, could you please help me with the approach to get it done.
    Here is the scenario:
    I have one table table_1,it contains 2 columns source_query , target_query.
    source_query and target_query are Select statements like source_query is Select name, age , valid from customer where customer_id=123456;
    I fetched the data from these columns into 2 strings
    select source_query into source_data from table_1;
    select target_query into target_data from table_1;
    Now out of these 2 I want to create 2 cursors, so that I can compare the column values one by one ( I am not using the  source minus target approach because of difference in the data type).
    I have to individually check the values.
    So here are the cursors:
    For source_data_value in ( EXECUTE immediate source_data)
    LOOP
    For target_data_value in (EXECUTE IMMEDIATE target_data)
    LOOP
    <executable statements>;
    END LOOP;
    END LOOP;
    But the cursor creation is failing in the procedure.
    Please let me know if it is possible to create a cursor using the execute immediate , if not what approach I should use other than this?

    Why exactly you are doing this inside a procedure. You can take the SQL's out and write a simple query to retrieve the data. Anyways, to work it out in a procedure, I can think of the below solution. I am trying to do away with Execute Immediate and use REF cursor. Please note that this is untested and just a try to present a possible solution which can be changed to implement your original requirement. I haven't done anything sort of this before, so if this approach doesn't approach, kindly ignore
    DECLARE
       TYPE TempTyp IS REF CURSOR;
       temp_cv   TempTyp;
      temp_cv_2 Temptyp;
       emp_rec  emp%ROWTYPE;
       source_data VARCHAR2(200);
         target_data  VARCHAR2(200);
       BEGIN
       source_data:= 'SELECT * FROM source tablej';
       target_Date :='select * from target table';
       OPEN temp_cv FOR source_data;
       LOOP
          FETCH temp_cv INTO emp_rec;
          EXIT WHEN emp_cv%NOTFOUND;
            OPEN   temp_cv_2 FOR target_data;
              FETCH Temp_cv_2 into  emp_rec  emp%ROWTYPE
                   loop
                        < And then your comparisons here >
         END LOOP:
         CLOST TEMP_CV_2;
       END LOOP;
       CLOSE temp_cv;
    END;
    Ishan

  • Execute immediate a procedure call

    Hi,
    I need some help, can some one EXPLAIN why its failing when i don't specify the test_proc in spec.
    i know this is not the right way of doing things. want to know why i need to specify the procedure name in spec.
    SQL> select * from v$version;
    BANNER                                                                         
    Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production   
    PL/SQL Release 11.2.0.2.0 - Production                                         
    CORE 11.2.0.2.0 Production                                                     
    TNS for Linux: Version 11.2.0.2.0 - Production                                 
    NLSRTL Version 11.2.0.2.0 - Production                                         
    SQL> CREATE OR REPLACE PACKAGE PkgTest AS
      2 
      3    --PROCEDURE test_proc;
      4    PROCEDURE run_proc;
      5  END PkgTest;
      6  /
    Package created.
    SQL>
    SQL>
    SQL> CREATE OR REPLACE PACKAGE BODY PkgTest AS
      2 
      3  PROCEDURE test_proc IS
      4    BEGIN
      5      dbms_output.put_line(' Test Proc');
      6  END test_proc;
      7 
      8  PROCEDURE run_proc IS
      9  BEGIN
    10      EXECUTE IMMEDIATE 'begin  PkgTest.test_proc; end;';
    11  END run_proc;
    12  END PkgTest;
    13  /
    Package body created.
    SQL> exec pkgtest.run_proc;
    BEGIN pkgtest.run_proc; END;
    ERROR at line 1:
    ORA-06550: line 1, column 16:
    PLS-00302: component 'TEST_PROC' must be declared
    ORA-06550: line 1, column 8:
    PL/SQL: Statement ignored
    ORA-06512: at "MPIEFP_DEV.PKGTEST", line 10
    ORA-06512: at line 1
    SQL> CREATE OR REPLACE PACKAGE PkgTest AS
      2 
      3    PROCEDURE test_proc;
      4    PROCEDURE run_proc;
      5  END PkgTest;
      6  /
    Package created.
    SQL> exec pkgtest.run_proc;
    Test Proc                                                                      
    PL/SQL procedure successfully completed.
    SQL> spool off

    Hi,
    If you tried to run this command from PL/SQL
    SQL>  EXEC  PkgTest.test_proc;
    do you understand why it would fail?  It fails in EXECUTE IMMEDIATE for the same reason.
    When you use EXECUTE IMMEDIATE, Oracle runs the dynamic command in a new, separate environment.  It knows nothing about the context from which it was called.  In particular, it doesn't know if it was called from inside a package or not, so procedures that are private to that package can't be called.
    Do you really need to use EXECUTE IMMEDIATE?  You obviously don't in the simple test scenario you posted, but I assume your real package is much more complicated.
    Why not simply include test_proc in the package spec?
    Is the problem that end users, who are allowed to cal run_proc, are not supposed to call test_proc direrctly?  If so, put them in different pacakges.  Declare test_proc in the spec of its package, but don't grant privileges on the package that end users.

  • Disadvantage with 'Execute Immediate'

    What is the disadvantage with 'EXECUTE IMMEDIATE'.

    I think you guys are missing the point here.
    None of the issues listed are 'EXECUTE IMMEDIATE' disadvantages.
    'EXECUTE IMMEDIATE' is a tool. Like DMS_SQL. Like ref cursors. Like explicit cursor. Like implicit cursors.
    A tool, any tool, needs to be used correctly. If you use a hammer and hit a nail so hard that it bents, causing the hammer to slip doing some serious damage to your thumb... whose fault it is?
    Is it The Hammer that is at fault here? Or is the user of that tool?
    There are no disadvantages to using 'EXECUTE IMMEDIATE'. It is a tool. But like all tools it needs to be used correctly and safely. Things like excessive hard parsing because of a severe lack of bind variables, or opening a hole for SQL injection, etc.. all these are symptoms of - and let's be blunt here - an ignorant developer. It has nothing to do with the tool 'EXECUTE IMMEDIATE'.
    And those same type of errors will be made by Mr Ignorant Developer using other tools in Oracle.
    Shoddy workmanship is not because of poor tools. Shoddy code is not because of using a specific feature (like execute immediate).
    The proper question to ask is thus not "what are the disadvantages of execute immediate", but rather "where should I typically use execute immediate and how?".
    Not every developer will know how to use every single tool in the toolbox (I sure don't know all the tools in the Oracle toolbox). So there is nothing wrong with asking.
    But asking what is "wrong" with a tool (aka "what are the disadvantages") is in my view seriously missing the point that a tool is there to solve very specific types of problems...
    That is what a developer should be after - How to use the tool correctly.

  • Problems using DDL & EXECUTE IMMEDIATE in package

    Hi...
    I have an 8i package in which I am trying to execute some DDL via EXECUTE IMMEDIATE to create temporary tables from which I then populate a REF_CURSOR by selecting from the last table created in the DDL. The problem is that the compiler doesn't seem to like the DDL.
    Here's what I'm using:
    CREATE OR REPLACE PACKAGE BODY NEREP_REF
    AS
    Procedure GetNE_REF (
    i_Node IN VARCHAR2,
    io_cursor IN OUT t_cursor )
    IS
    sql_stmt varchar2(200);
    v_cursor t_cursor;
    BEGIN
    sql_stmt := 'CREATE TABLE tmp AS SELECT * FROM nerep4;';
    EXECUTE IMMEDIATE sql_stmt;
    OPEN v_cursor FOR
    SELECT NE_Node, NE_Type, EHA, Status, Curr_Func, TP_Name,
    Order_Item_Name, Required_Start, Required_End, Trail_Name
    FROM tmp
    WHERE NE_Node = i_Node ;
    io_cursor := v_cursor;
    END GetNE_REF;
    END NEREP_REF;
    The problem is that when I compile the package I get the errors below:
    SQL> @sp_nerep_body
    Warning: Package Body created with compilation errors.
    SQL> show err
    Errors for PACKAGE BODY NEREP_REF:
    LINE/COL ERROR
    20/7 PL/SQL: SQL Statement ignored
    23/14 PLS-00201: identifier 'NE_NODE' must be declared
    So it seems that it doesn't like the DDL (have I got the sql_stmt assignment in the wrong place maybe?) and then it complains it can't find the columns, which is reasonable because of course it doesn't know that the table 'tmp' comes from the result of the DDL statement!
    If I change the table name in the 'OPEN v_cursor FOR' select clause to a table that already exists (ie: not created in this package) it runs just fine and I get the data I asked for... the problem is that I need to create this table on the fly by using DDL in my package!
    This is driving me crazy - basically I need to be able to execute DDL to do various 'create table ... as select ... from ...' statements which eventually builds a final table which I then want to populate using a REF_CURSOR so I can return the results back to ASP via ADO... but I just can't get the DDL bit to work no matter what I try!!
    Can anyone see what I'm doing wrong here?
    Mike.
    null

    Here are a some ideas to try:
    Remove the extra semicolon from your sql_stmt, so that line reads:
    sql_stmt := 'CREATE TABLE tmp AS SELECT * FROM nerep4';
    Ensure that you have proper privileges as an individual user, not just through a role, by:
    connecting to the database using username system and password manager and granting yourself the proper privileges. For example, if you are user SCOTT, then:
    SQL> GRANT CREATE TABLE TO SCOTT;
    Then, exit and connect as yourself and try to compile and execute your procedure again.
    If that still doesn't work, try testing one little piece at a time until you can identify the part that causes trouble. For example, start with a procedure that does nothing but try to create the tmp table using execute immediate, then add the other pieces, then try to put the procedure in a package.

  • EXECUTE IMMEDIATE within Procedure doesn't work!!

    Hi,
    I have a code in which the procedure is successfully created, but when I try to check if the table TEST_TABLE is created (ex, DESC TEST_TABLE) it generates an error:
    ORA-04043: object TEST_TABLE does not exist
    Which means that my EXECUTE IMMEDIATE didn't work within the procedure for some reason, while it works perfectly alone without the procedure!!
    Hope you help me with this..
    Here's the my code:
    CREATE OR REPLACE PROCEDURE TEST_IMM1
    AS
    BEGIN
    EXECUTE IMMEDIATE ' CREATE TABLE TEST_TABLE (ITEM_DESC VARCHAR2(10))';
    END;
    --Procedure created.
    DESC TEST_TABLE
    ERROR:
    ORA-04043: object TEST_TABLE does not exist

    user11921409 wrote:
    Thanks a lot Ahmed, yes it worked after executing the procedure and table is created. But that's only one part of the problem, in which after dynamically creating the table TEST_TABLE, I should be able to insert data to it such as:
    CREATE OR REPLACE PROCEDURE TEST_IMM1
    AS
    BEGIN
    EXECUTE IMMEDIATE ' CREATE TABLE TEST_TABLE (ITEM_DESC VARCHAR2(10))';
    END;
    --Procedure created.
    CREATE OR REPLACE PROCEDURE INSERT_TEST_TABLE
    AS
    BEGIN
    TEST_IMM1;
    INSERT INTO TEST_TABLE VALUES ('A');
    END;
    --Warning: Procedure created with compilation errors.
    PL/SQL: SQL Statement ignored
    PL/SQL: ORA-00942: table or view does not exist
    Can you tell me how to use INSERT with EXECUTE IMMEDIATE.
    Thanks :)Just as an FYI, this is really not a good methodology to program in Oracle. If you're doing this for purely learning purposes then it's less 'bad', but if you plan on programming as a career in Oracle, this isn't the method you'd want to adopt (i'll not say there is NEVER a case for something like this, but it's a small percentage of the typical use cases).
    You would do better to create a global temporary table if you need a table to muck around with in a session, or create a permanent table (likely not via procedures) and have it persist in the schema of your choice.
    Utilizing execute immediate for insert statements, especially without BIND VARIABLES, will create a sad day for your database.

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

  • 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 '&#0124; &#0124;p_Job_Code );
    DBMS_OUTPUT.PUT_LINE('p_Parameter_Entry '&#0124; &#0124;p_Parameter_Entry );
    FOR Item IN CTable_Used_By_Report
    LOOP
    StrSql := 'DELETE '&#0124; &#0124;Item.TABLE_OWNER&#0124; &#0124;'.'&#0124; &#0124;Item.TABLE_NAME&#0124; &#0124;' T WHERE EXISTS ( SELECT 1 FROM USERBATCH.HISTORY_JOB H WHERE H.USER_ID = ' ;
    StrSql := StrSql&#0124; &#0124;''''&#0124; &#0124;p_User_Id&#0124; &#0124;''''&#0124; &#0124;' AND H.Job_Code = '&#0124; &#0124;''''&#0124; &#0124;p_Job_Code&#0124; &#0124;''''&#0124; &#0124;' AND H.PARAMETER_ENTRY = '&#0124; &#0124;'''' &#0124; &#0124;p_Parameter_Entry&#0124; &#0124;''''&#0124; &#0124;' AND T.SESSION_ID = H.TRANSACTION_ID)';
    DBMS_OUTPUT.PUT_LINE(StrSql);
    DBMS_OUTPUT.PUT_LINE(Item.TABLE_OWNER&#0124; &#0124;'.'&#0124; &#0124;Item.TABLE_NAME);
    EXECUTE IMMEDIATE StrSql;
    END LOOP;
    DBMS_OUTPUT.PUT_LINE('DELETE USERBATCH.HISTORY_JOB WHERE USER_ID ='''&#0124; &#0124; p_User_Id &#0124; &#0124;'''
    AND Job_Code ='''&#0124; &#0124; p_Job_Code &#0124; &#0124;''' AND PARAMETER_ENTRY = '''&#0124; &#0124; p_Parameter_Entry &#0124; &#0124;'''');
    EXECUTE IMMEDIATE 'DELETE USERBATCH.HISTORY_JOB WHERE USER_ID ='''&#0124; &#0124; p_User_Id &#0124; &#0124;'''
    AND Job_Code ='''&#0124; &#0124; p_Job_Code &#0124; &#0124;''' AND PARAMETER_ENTRY = '''&#0124; &#0124; p_Parameter_Entry &#0124; &#0124;'''';
    COMMIT;
    EXCEPTION
    WHEN OTHERS THEN
    ROLLBACK;
    p_Status := 0;
    DBMS_OUTPUT.PUT_LINE( SUBSTR(SQLERRM,1,255) );
    END DeleteOld_Job;
    TIA
    null

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

  • [Solved] Reference apex_application.g_fXX in "execute immediate" statement

    Hi!
    I created a dynamically generated tabular form - the number of columns is not known in advanced. Each cell of the form is a text item generated with apex_item.text().
    I want to write an after-submit process that saves the values from the form into a database table. In this process I already know how many columns there are in the report so I want to do the following:
    --for each row...
    for i in 1..apex_application.g_f01.count loop
      -- and for each column in that row (number of columns is in v_col_count)
      for j in 1..v_col_count loop
        -- get the value of text item
        v_query := 'select apex_application.g_f0' || j || '(' || i || ')' || ' from dual';
        execute immediate v_query into v_value;
        -- now do some DML with v_value
      end loop;
    end loop;The problem is that I get an error: ORA-06553: PLS-221: 'G_Fxx' is not a procedure or is undefined where xx is the number from the generated query.
    My question is - am I doing something wrong or is is just not possible to reference apex_application.g_fxx in "execute immediate"? Will I have to manually check for all 50 possibilites of apex_application.g_fxx? Is there another way?
    TIA,
    Jure

    Well now I know what was wrong and what you were trying to tell me - apex_application.g_fxx is not visible in "plain" SQL. And now I also have a solution to this problem. The point is to wrap the select statement with begin - end block so that the statement is rendered as pl/sql:
    --for each row...
    for i in 1..apex_application.g_f01.count loop
      -- and for each column in that row (number of columns is in v_col_count)
      for j in 1..v_col_count loop
        -- get the value of text item
        v_query := 'begin select apex_application.g_f0' || j || '(:i)' || ' into :x from dual; end;';
        execute immediate v_query using i, out v_value;
        -- now do some DML with v_value
      end loop;
    end loop;This works great :).
    Jure

Maybe you are looking for