PLSQL table in EXECUTE IMMEDIATE

Hi All,
This is just a sample code.Table name may be changed in next run.
when I run this program ,getting error in EXECUTE IMMEDIATE -" V_FIELDS invalid identifier",Also the way I am doing,that's right?
create table TEMP
col1 VARCHAR2(200),
col2 VARCHAR2(200),
col3 DATE )
DECLARE
v_fields dbms_sql.varchar2a;
v_col_str VARCHAR2(200);
v_insert VARCHAR2(200);
v_idx INTEGER := 0;
v_tab VARCHAR2(30) := 'TEMP';
BEGIN
FOR i IN (SELECT s.column_name, s.data_type
FROM user_tab_cols s
WHERE s.table_name = v_tab
ORDER BY s.column_id)
LOOP
v_col_str := v_col_str || i.column_name || ',';
IF i.data_type = 'DATE'
THEN
v_insert := v_insert || 'TO_DATE(v_fields(' || v_idx || '),' ||
'''MM/DD/YYYY''' || '),';
ELSE
v_insert := v_insert || 'v_fields(' || v_idx || '),';
END IF;
v_idx := v_idx + 1;
END LOOP;
v_insert := '( ' || RTRIM(v_insert, ',') || ' )';
v_col_str := 'INSERT INTO ' || v_tab || ' ( ' || RTRIM(v_col_str, ',') ||
' ) VALUES ';
dbms_output.put_line(v_col_str || v_insert);
v_fields(0) := 1;
v_fields(1) := 'AB';
v_fields(2) := SYSDATE;
EXECUTE IMMEDIATE v_col_str || v_insert;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Err: ' || SQLERRM);
END;
Thanks,

The dynamic SQL generated is
INSERT INTO TEMP ( COL1,COL2,COL3 ) VALUES ( v_fields(0),v_fields(1),TO_DATE(v_fields(2),'MM/DD/YYYY') ) PL/SQL engine sends this SQL to SQL engine. And guess what, SQL Engine has no clue what v_fields is. Why? because v_fields a private variable defined in a PL/SQL block for which SQL Engine has zero access.
Try this
DECLARE
    v_fields  dbms_sql.varchar2a;
    v_col_str VARCHAR2(200);
    v_insert  VARCHAR2(200);
    v_idx     INTEGER := 0;
    v_tab     VARCHAR2(30) := 'TEMP';
BEGIN
    FOR i IN (SELECT s.column_name, s.data_type
                FROM user_tab_cols s
               WHERE s.table_name = v_tab
               ORDER BY s.column_id)
    LOOP
        v_col_str := v_col_str || i.column_name || ',';
        IF i.data_type = 'DATE'
        THEN
            v_insert := v_insert || 'TO_DATE(:' || v_idx || ',' ||
                        '''MM/DD/YYYY''' || '),';
        ELSE
            v_insert := v_insert || ':' || v_idx || ',';
        END IF;
        v_idx := v_idx + 1;
    END LOOP;
    v_insert  := '( ' || RTRIM(v_insert, ',') || ' )';
    v_col_str := 'INSERT INTO ' || v_tab || ' ( ' || RTRIM(v_col_str, ',') ||
                 ' ) VALUES ';
    v_fields(0) := 1;
    v_fields(1) := 'AB';
    v_fields(2) := to_char(SYSDATE, 'MM/DD/YYYY');
    execute immediate v_col_str || v_insert using v_fields(0), v_fields(1), v_fields(2);
END;
/ I personally don't encourage dynamic SQL. Dynamic SQL is always a pain and a result of bad design.
And the most worst thing, the thing that is terrible than dynamic SQL is this
WHEN OTHERS THEN
dbms_output.put_line('Err: ' || SQLERRM);
END; Whats the logic and possible benefit behind this code? Its NONE. Don't do that, NEVER. WHEN OTHERS without a RAISE is a bug in your code. So never do that. And DBMS_OUTPUT is not the correct way to render error message to user.

Similar Messages

  • Create temp table using EXECUTE IMMEDIATE

    Is there any performance issue in creating globally temp table
    using EXECUTE IMMEDIATE or creating globally temp table from
    SQL PLUS.
    Any response will be greatly appreciated.
    null

    Anish,
    Creating tables is likely to be an expensive operation.
    Performance issues can only be considered in comparison to
    alternatives.
    Alternatives include: PLSQL tables, cursors and/or recoding so
    that tmp tables are not required. (One of our consultants reckons
    that sqlserver temp tables are usually used to get around
    limitations in sqlserver, ie slightly more complicated sql
    statements could be used instead of simpler sql and temporary
    tables).
    I would think creating the temp table once during sqlplus would
    be cheaper than creating and deleting it repeatedly at run time.
    Note that EXECUTE IMMEDIATE may do an implicit commit (dbms_sql
    certainly does). This may be got over my using the PRAGMA
    AUTONOMOUS_TRANSACTION; direction which places a
    procedure/function in a seperate transaction.
    Turloch
    P.S. We have some difficulty in getting information back from the
    field/customer sites. If you have questions and answers that are
    likely to be useful to other Oracle Migration Workbench
    users, and migrators in general, please send them in for possible
    inclusion in our Frequently Asked Question list.
    Oracle Migration Workbench Team
    Anish (guest) wrote:
    : Is there any performance issue in creating globally temp table
    : using EXECUTE IMMEDIATE or creating globally temp table from
    : SQL PLUS.
    : Any response will be greatly appreciated.
    Oracle Technology Network
    http://technet.oracle.com
    null

  • Selecting data from a table using Execute Immediate in 9i

    Hi,
    I was wondering how I would be able to do a SELECT on a table using EXECUTE IMMEDIATE. When I tried it (with the proc below), I got the following below. Can anyone tell me what I am doing wrong?
    Using Scott/Tiger I tried this:
    SQL> ed
    Wrote file afiedt.buf
    1 CREATE OR REPLACE PROCEDURE P2
    2 IS
    3 v_SQL VARCHAR2(100);
    4 BEGIN
    5 v_SQL := 'Select * from Emp';
    6 EXECUTE IMMEDIATE v_SQL;
    7* END;
    SQL> /
    Procedure created.
    SQL> exec p2
    PL/SQL procedure successfully completed.
    SQL> set serveroutput on
    SQL> exec p2
    PL/SQL procedure successfully completed.
    SQL>
    Thanks in advance.
    Sincerely,
    Nikhil Kulkarni

    1 CREATE OR REPLACE PROCEDURE P2
    2 IS
    3 v_SQL VARCHAR2(100);
    erec emp%rowtype;
    4 BEGIN
    5 v_SQL := 'Select * from Emp';
    6 EXECUTE IMMEDIATE v_SQL into erec;
    7* END;
    SQL> /

  • CREATE TEMPORARY TABLE USING EXECUTE IMMEDIATE

    Hi All,
    i have a question,
    how can i create a temporary table using EXECUTE IMMEDIATE ??
    Like:
    CREATE GLOBAL TEMPORARY table new_table as (Select * from old_table);
    Thanks,
    Edited by: xDeviates on Jun 11, 2012 3:13 PM

    It looks like you are approaching the problem incorrectly. As I suggested in Dynamic Select, it sounds like you, at most, want a function that returns a SYS_REFCURSOR (it's still not obvious to me why you would even want/ need to resort to dynamic SQL in the first place)
    CREATE OR REPLACE FUNCTION get_dynamic_cursor( p_table_name IN VARCHAR2 )
      RETURN sys_refcursor
    IS
      l_rc sys_refcursor;
    BEGIN
      OPEN l_rc FOR 'SELECT * FROM ' || dbms_assert.sql_object_name( p_table_name );
      RETURN l_rc;
    END;which you can then call from your application
    SQL> variable rc refcursor;
    SQL> exec :rc := get_dynamic_cursor( 'EMP' );
    PL/SQL procedure successfully completed.
    SQL> print rc
         EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM
        DEPTNO
          7369 SMITH      CLERK           7902 17-DEC-80        801
            20
          7499 ALLEN      SALESMAN        7698 20-FEB-81       1601        300
            30
          7521 WARD       SALESMAN        7698 22-FEB-81       1251        500
            30
         EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM
        DEPTNO
          7566 JONES      MANAGER         7839 02-APR-81       2976
            20
          7654 MARTIN     SALESMAN        7698 28-SEP-81       1251       1400
            30
          7698 BLAKE      MANAGER         7839 01-MAY-81       2851
            30
         EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM
        DEPTNO
          7782 CLARK      MANAGER         7839 09-JUN-81       2451
            10
          7788 SCOTT      ANALYST         7566 19-APR-87       3001
            20
          7839 KING       PRESIDENT            17-NOV-81       5001
            10
         EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM
        DEPTNO
          7844 TURNER     SALESMAN        7698 08-SEP-81       1501          0
            30
          7876 ADAMS      CLERK           7788 23-MAY-87       1101
            20
          7900 JAMES      CLERK           7698 03-DEC-81        951
            30
         EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM
        DEPTNO
          7902 FORD       ANALYST         7566 03-DEC-81       3001
            20
          7934 MILLER     CLERK           7782 23-JAN-82       1301
            10
    14 rows selected.Justin

  • Problem with alter table in execute immediate

    We have PL/SQL scripts which modify the data structure, add data etc to en existing database. These scripts basically ensure that the db is compatible with what the software expects.
    The reason for doing it in PL/SQL rather than SQL script is A) The scripts are launched using GUI so that they are more user friendly. sqlplus is launched as a background process which executes these scripts. All the scripts have EXIT FAILURE WHENEVER SQLERROR as first line to ensure that the control does not hang in the sqlplus background process.
    Going from one version to other, we have added a few tables to the database and also modified a few tables. since (i think) DDL is not allowed in PL/SQL block, we had to resort to putting them in EXECUTE IMMEDIATE enclosures.
    Now for the real question,
    If I create a table using EXECUTE IMMEDIATE clause, I can immediately have insert as a next statement to insert data in this table. but, if I alter the table and add a column to the existing table, I cannot immediately add data to that column, it throws an error saying 'invalid identifier'
    At code level, the following is allowed :
    EXECUTE IMMEDIATE 'CREATE TABLE SP_TEST_TABLE
                             ID     NUMBER,
                             NAME     Varchar2(40)
    INSERT INTO SP_TEST_TABLE(ID, NAME) Values(1, 'SP');
    but I get error for the following :
    EXECUTE IMMEDIATE 'ALTER TABLE SP_TEST_TWO ADD
                        ANOTHER_COLUMN     number
    UPDATE     SP_TEST_TWO SET          ANOTHER_COLUMN = 1;
    In this case, it says ANOTHER_COLUMN invalid identifier
    Does anybody know why?
    any workaround will be greatly appreciated.
    --SP                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

    Friends,
    Thanks to all of you for your help. The spelling mistakes might have occurred becuase i changed the actual script to something 'short and complete' to show the problem.
    I could solve the problem by having more than one PL/SQL block within my file. something like :
    BEGIN
    --alter table statements here
    END;
    BEGIN
    --insert the values in column here.
    END;
    I am still not sure why the error is presented only on alter table statement and not for create table statement. Probably somebody with the knowledge of oracle internals will be able to throw more light on it. I am trying to get the naswers, if I get the answer, I'll surely post it here.
    Regards,
    --Saurabh                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

  • Need suggestion on PLSQL Create and EXECUTE IMMEDIATE

    Most of you already know plsql doesn't like create table, so we have to use EXECUTE IMMEDIATE for creating table. What if I want to see if the table exist, if not then create the table, later I will insert data into that table.
    My problem is it returned me the error saying I am try to insert into a non existing table when trying to compile my code. I think plsql doesn't pick up the execute statement.
    what I did is, both create and insert are executed by using EXECUTE IMMEDIATE. Anyone have such experience before and willing to share your knowledge?
    PS: I am having same problem for creating sequence as well.

    I think plsql doesn't pick up the execute statement.Since it is a runtime instruction, it will pick it up at runtime. but to be able to run, it needs to compile the code and in order to compile (so it can run) the code it needs that table/sequence you are referencing to exist already. So, you need to run the code to get the table and run needs to compile the code and compile needs the table to compile. can't go from here to there when you try to mix dynamic sql with static sql on the same object within the same program unit (or dependent units).

  • Oracle 11G Copying a table using execute immediate

    I want to copy the contents of one table into another using execute immediate.
    This keeps failing with the following error
    ORA-00903: invalid table name
    ORA-06512: at "TABLE_COPY", line 6
    ORA-06512: at line 8
    create or replace
    procedure TABLE_COPY(
    TABLE1 varchar2,
    TABLE2 varchar2)
    is
    begin
    execute immediate 'insert into '||TABLE2||' (select * from '||TABLE1||')';
    end;
    Edited by: user9213000 on 24-Jan-2013 07:38

    user9213000 wrote:
    I want to copy the contents of one table into another using execute immediate.
    This keeps failing with the following error
    ORA-00903: invalid table name
    ORA-06512: at "TABLE_COPY", line 6
    ORA-06512: at line 8
    create or replace
    procedure TABLE_COPY(
    TABLE1 varchar2,
    TABLE2 varchar2)
    is
    begin
    execute immediate 'insert into '||TABLE2||' (select * from '||TABLE1||')';
    end;
    Edited by: user9213000 on 24-Jan-2013 07:38The standard advice when (ab)using EXECUTE IMMEDIATE is to compose the SQL statement in a single VARCHAR2 variable
    Then print the variable before passing it to EXECUTE IMMEDIATE.
    COPY the statement & PASTE into sqlplus to validate its correctness.

  • Problem in using CREATE TABLE with Execute Immediate

    I'm trying to create a table using Native Dynamic SQL. the code of the pl/sql block is
    BEGIN
    EXECUTE IMMEDIATE 'create table demo (ddate date)';
    END;
    The problem is that the above block is executed successfully as an anonymous PL/SQL block. The same block when written in a procedure it gives an error
    "ORA-01031 Insufficient privelages"
    at the time of execution. The procedure is complied successfully.
    null

    Your user needs direct system privs to create tables. You are receiving your privs properly by the role RESOURCE. Connect as system and grant CREATE TABLE directly to your user - that should do it.
    Regards
    Peter Larsen

  • Creation of table through execute immediate

    Im trying to create a table through the following procedure.
    create or replace procedure tab_creat
    v_sql_Stmt varchar2(100);
    begin
    v_sql_stmt:='create table test_prc (num number)';
    execute immediate v_sql_stmt;
    end;
    The procedure is getting compiled but it is not getting executed.
    Im getting the following error.
    ERROR at line 1:
    ORA-01031: insufficient privileges
    ORA-06512: at "SCOTT.TAB_CREAT", line 6
    ORA-06512: at line 1
    I also gave the DBA privilleges for the particular schema but still im getting the following error

    1) Creating a table (or any object) dynamically in a stored procedure is almost always a bad idea in Oracle.
    2) Stored procedures (of the default definer's rights variety) do not have access to privileges granted through a role. The procedure owner would need to have the CREATE TABLE privilege granted directly to him, not granted via a role.
    Justin

  • Inserting variables to table by "execute immediate' statement

    EXECUTE IMMEDIATE 'INSERT INTO aTABLETKA_HISTORY
    (update_id,
    update_type,
    update_date,
    old_db_version,
    description,
    patch_number)
    values
    (' || m_id(v_rec) || ',
    '||m_package(v_rec)||',
    ''07-NOV-07'',
    ''snezi'',
    '||m_desc(v_rec)||',
    '||m_new(v_rec)||')';
    ORA-00917: missing comma
    ORA-06512: at line 142
    i cannot solve this,. can anybody help me?
    i have simillar insert:
    EXECUTE IMMEDIATE 'INSERT INTO ab_table_VERSION(property,version) values (''wiz_datalink'',' || my_version || ')';
    and this one statement work correctly

    Do NOT use "execute immediate". What is the reason for trying it this way?
    If the column update_date is of type date, then you have a bug in the code, as you are trying to insert a string. If it is not a date data type, then you have a bug, because it is not of type date.
    What is the outcome of:
    INSERT INTO aTABLETKA_HISTORY (update_id, update_type, update_date,
          old_db_version, description, patch_number)
       values (m_id(v_rec), m_package(v_rec), to_date('07-NOV-2007', 'dd-MON-yyyy'),
          snezi, m_desc(v_rec), m_new(v_rec) )
    /

  • Unable to INSERT PL/SQL  record with EXECUTE IMMEDIATE

    Hi All,
    I am selecting data from a source table and after some modification inserting into a target table. Source and target table name are available at run time. You can say only source table structure is fixed.
    I have crated a pl/sql table of type source record and inserting record by record in target table using execute immediate. But I am not able to write
    EXECUTE IMMEDIATE string USING pl_sql_table(index); and getting error as
    PLS-00457: expressions have to be of SQL types
    Please see the part of code below. Is it possible to use FORALL with dynamic sql like
    FORALL pl_sql_table.FIRST .. pl_sql_table.COUNT
    EXECUTE IMMEDIATE .... pl_sql_table(j); -- Like this.
    Please suggest why I am not able to write record here. I also want to replace 'INSERT in a loop' with a single INSERT statement out of the loop, to upload whole pl_sql table into target table in one go.
    Thanks,
    Ravi
    DECLARE
        TYPE rec_tab_CMP IS RECORD
         model_id          NUMBER(38),   
         absolute_rank          NUMBER(5)         
        v_rec_tab_CMP  rec_tab_CMP;
        TYPE t_rec_tab_CMP IS TABLE OF v_rec_tab_CMP%TYPE INDEX BY BINARY_INTEGER;
        v_records_CMP               t_rec_tab_CMP;
        rc                          SYS_REFCURSOR;
        v_old_table_name            VARCHAR2(30); -- passed from parameter 
        v_new_table_name            VARCHAR2(30); -- passed from parameter 
        dyn_str                     VARCHAR2(500);
        v_columns_str               VARCHAR2(200) := ' model_id, absolute_rank ';
    BEGIN
           EXECUTE IMMEDIATE 'CREATE TABLE '|| v_new_table_name || ' AS SELECT * FROM ' || v_old_table_name ||' WHERE 1 = 2 ' ;
         OPEN rc FOR 'SELECT '|| v_columns_str ||' FROM '|| v_old_table_name;
         FETCH rc BULK COLLECT INTO v_records_CMP;
         FOR j IN 1..v_records_CMP.COUNT
         LOOP
            v_records_CMP(j).model_id := 1; -- Do someting here, This thing can be performed in SQL stmt directly.
            dyn_str := 'INSERT INTO '|| v_new_table_name ||' ( '|| v_columns_str || ' ) VALUES (:1, :2) ';
            EXECUTE IMMEDIATE dyn_str USING v_records_CMP(j).model_id          ,
                                v_records_CMP(j).absolute_rank     ;
         -- Here in place of two columns I want to use one record like
         -- EXECUTE IMMEDIATE dyn_str USING v_records_CMP(j);
         -- But it is giving me error like
            --          EXECUTE IMMEDIATE dyn_str USING v_records_st(j);
            --   PLS-00457: expressions have to be of SQL types
         END LOOP;
         CLOSE rc;
    END;
    /

    You cannot bind PL/SQL record types to dynamic SQL.
    Possibly you could work around this by declaring the INDEX-BY table of records at package specification level, e.g.
    Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production
    SQL> CREATE PACKAGE package_name
      2  AS
      3     TYPE tt_emp IS TABLE OF emp%ROWTYPE;
      4     t_emp tt_emp;
      5  END package_name;
      6  /
    Package created.
    SQL> CREATE TABLE new_emp
      2  AS
      3     SELECT *
      4     FROM   emp
      5     WHERE  1 = 0;
    Table created.
    SQL> DECLARE
      2     v_table_name user_tables.table_name%TYPE := 'NEW_EMP';
      3  BEGIN
      4     SELECT *
      5     BULK COLLECT INTO package_name.t_emp
      6     FROM   emp;
      7
      8     EXECUTE IMMEDIATE
      9        'BEGIN ' ||
    10        '   FORALL i IN 1 ..package_name.t_emp.COUNT ' ||
    11        '      INSERT INTO ' || v_table_name ||
    12        '      VALUES package_name.t_emp (i); ' ||
    13        'END;';
    14  END;
    15  /
    PL/SQL procedure successfully completed.
    SQL> SELECT empno, ename
      2  FROM   new_emp;
         EMPNO ENAME
          7369 SMITH
          7499 ALLEN
          7521 WARD
          7566 JONES
          7654 MARTIN
          7698 BLAKE
          7782 CLARK
          7788 SCOTT
          7839 KING
          7844 TURNER
          7876 ADAMS
          7900 JAMES
          7902 FORD
          7934 MILLER
    14 rows selected.
    SQL>

  • Problem in  EXECUTE IMMEDIATE

    I need to update certain columns of a table .
    But the columns are dynamic. i can update 1,20r 3 or more columns of that table.
    I tried executing with the Execute immediate statement.
    But i am getting the error (ORA-01747)
    :1(below in code) Contains the column name along with the values. (Example:Column2=Column2.value,Column3=Column3.value)
    There can be more than 3 or more columns to be updated.
    CREATE OR REPLACE PROCEDURE PR_Bulk_CA(pn_SSCA_ID_VARRAY          BULK_UPDATE_CA_VARRAY
                                          ,pv_set_string              Varchar2
                                          ,pn_success                 OUT number
                                          Is
    sql_stmt  VARCHAR2(32000);
    BEGIN
    sql_stmt:= 'update table_A
                   SET :1
               WHERE  ID IN (select ID from table_A ca
                       where  ca.status in (20700,20710,20720)
                         and  ca.id in (select * from table(:2)))';
    EXECUTE IMMEDIATE sql_stmt USING pv_set_string,pn_SSCA_ID_VARRAY;                     
    COMMIT;
    pn_success:=0;
    EXCEPTION
        WHEN OTHERS THEN
    pn_success:=-1;
    END PR_Bulk_CA;

    So?
    By concatenating the column-name-update-string to the rest of the dynamic statement you get what you want.
    if your pv_set_string has:
      column_a = 17, column_b = 15, column_c = 12in it, the statement generated will handle this...
    I did not state not to do dynamic sql but not to pass the column names using bind variables, as this will not work. The reason therefore is, that the parser need to know the names of the columns to figure out, whether you passed a syntactical correct statement. The parser will not know the content of a bind variable as this is not needed for the syntax (and access rights) check.
    hth

  • 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 and CLOB

    Hi All,
    Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
    I am getting error when trying to use CLOB with execute immediate.
    DECLARE
    v_clob CLOB;
    BEGIN
    EXECUTE IMMEDIATE 'SELECT DBMS_METADATA.GET_DDL(''TABLE'',''T_FDB_TMP'') from dual'
               INTO v_clob_part_ddl;
    EXECUTE IMMEDIATE 'DROP TABLE T_FDB_TMP';
    EXECUTE IMMEDIATE to_char(v_clob_part_ddl);
    END;
    ORA-06502: PL/SQL: numeric or value error
    ORA-06512: at line 1
    ORA-06502: PL/SQL: numeric or value error
    ORA-31605: the following was returned from LpxXSLResetAllVars in routine kuxslResetParams:
    LPX-1: NULL pointer
    ORA-06512: at line 3
    06502. 00000 -  "PL/SQL: numeric or value error%s"Please help

    If you can't upgrade to 11g then you'll have to use DBMS_SQL package...
    e.g.
    SQL> ed
    Wrote file afiedt.buf
      1  declare
      2    v_large_sql  CLOB;
      3    v_num        NUMBER := 0;
      4    v_upperbound NUMBER;
      5    v_sql        DBMS_SQL.VARCHAR2S;
      6    v_cur        INTEGER;
      7    v_ret        NUMBER;
      8  begin
      9    -- Build a very large SQL statement in the CLOB
    10    LOOP
    11      IF v_num = 0 THEN
    12        v_large_sql := 'CREATE VIEW vw_tmp AS SELECT ''The number of this row is : '||to_char(v_num,'fm0999999')||''' as col1 FROM DUAL';
    13      ELSE
    14        v_large_sql := v_large_sql || ' UNION ALL SELECT ''The number of this row is : '||to_char(v_num,'fm0999999')||''' as col1 FROM DUAL';
    15      END IF;
    16      v_num := v_num + 1;
    17      EXIT WHEN DBMS_LOB.GETLENGTH(v_large_sql) > 40000 OR v_num > 800;
    18    END LOOP;
    19    DBMS_OUTPUT.PUT_LINE('Length:'||DBMS_LOB.GETLENGTH(v_large_sql));
    20    DBMS_OUTPUT.PUT_LINE('Num:'||v_num);
    21    --
    22    -- Now split that large SQL statement into chunks of 256 characters and put in VARCHAR2S array
    23    v_upperbound := CEIL(DBMS_LOB.GETLENGTH(v_large_sql)/256);
    24    FOR i IN 1..v_upperbound
    25    LOOP
    26      v_sql(i) := DBMS_LOB.SUBSTR(v_large_sql
    27                                 ,256 -- amount
    28                                 ,((i-1)*256)+1 -- offset
    29                                 );
    30    END LOOP;
    31    --
    32    -- Now parse and execute the SQL statement
    33    v_cur := DBMS_SQL.OPEN_CURSOR;
    34    DBMS_SQL.PARSE(v_cur, v_sql, 1, v_upperbound, FALSE, DBMS_SQL.NATIVE);
    35    v_ret := DBMS_SQL.EXECUTE(v_cur);
    36    DBMS_OUTPUT.PUT_LINE('View Created');
    37* end;
    SQL> /
    Length:40015
    Num:548
    View Created
    PL/SQL procedure successfully completed.
    SQL> select count(*) from vw_tmp;
      COUNT(*)
           548
    SQL> select * from vw_tmp where rownum <= 10;
    COL1
    The number of this row is : 0000000
    The number of this row is : 0000001
    The number of this row is : 0000002
    The number of this row is : 0000003
    The number of this row is : 0000004
    The number of this row is : 0000005
    The number of this row is : 0000006
    The number of this row is : 0000007
    The number of this row is : 0000008
    The number of this row is : 0000009
    10 rows selected.
    SQL>

  • Single quotes problem with execute immediate

    Thanks for considering to solve the issue.
    [i]Situation:
    I am trying to create a procedure to perform a set of operations. As part of that, I am trying to create a table using execute immediate statement. This create table statement has a select sub query where p_LOB3 is the variable for the procedure of datatype varchar2.
    Problem :
    I need to pass the variable p_LOB3 as single quoted as it is of type Varchar2. Also I need to enclose the entire create table query within single quotes. How do I specify this as it is throwing an error when the PL/SQL engine is parsing the single quotes in the query used twice for different purposes as mention earlier.
    Query:
    execute immediate'create table test5 as select min(contract_number)as contract_number,contact_id,max(line_of_business) as line_of_business from mytable group by contact_id having min(contract_number) = max(contract_number) and max(Line_of_business) = 'p_LOB3' ';

    Thank you Todd,
    Is just worked fine.
    New issue is: I am not able to put 2 such statements in a single procedure and execute. Before I give parameters to the procedure, PL/SQL engine is actually creating a view of the mytable and naming is as test5, as a result I am not able to create a table as there is a view with the same name.
    Right now, the workaround I am using is to create three different procedures to create three such tables. I know this is not a good idea....can you please tell me if there is a better way.
    Procedure
    CREATE OR REPLACE PROCEDURE SP_CREATE_0_0(p_LOB1 IN varchar2, p_LOB2 IN varchar2)
    IS
    BEGIN
    execute immediate 'create table test5 as select min(contract_number) as
    contract_number,contact_id,max(line_of_business) as line_of_business from
    mytable group by contact_id having min(contract_number) = max(contract_number)
    and max(Line_of_business) = ' ' ' || p_LOB1 || ' ' ' ';
    execute immediate 'create table test5 as select min(contract_number) as
    contract_number,contact_id,max(line_of_business) as line_of_business from
    mytable group by contact_id having min(contract_number) = max(contract_number)
    and max(Line_of_business) = ' ' ' || p_LOB1 || ' ' ' ';
    END SP_CREATE_0_0;
    /

Maybe you are looking for