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

Similar Messages

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

  • 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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

  • 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

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

  • 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) )
    /

  • Ssis sql command how to make it working with temp table #check , does not recognize though i created separate above data flow task a temp table through execute sql task.

    CREATE TABLE #check(
    reseller_account_id bigint NOT NULL PRIMARY KEY
    ,customer_id int NOT NULL
    INSERT INTO #check(reseller_account_id, customer_id)
    SELECT reseller_account_id, customer_id
    FROM ods.derived.postal_accounts pa
    JOIN ods.derived.bridge_accounts ba
    ON pa.bridge_id = ba.bridge_id
    AND pa.primary_multi_user_account_flag = 1
    WHERE promotion_code LIKE 'England-[01234]'
    AND reseller_account_id > 0;
    SELECT [reseller_id]
    ,c.reseller_account_id
    ,t.[postage_id]
    ,t.[customer_id]
    ,t.[mail_class_id]
    ,[mail_class_name]
    ,[mail_type_id]
    ,[mail_type_description]
    ,[org_zip_code]
    ,[dest_zip_code]
    ,[zone]
    ,t.[confirmation_number]
    ,[weight_category]
    ,[usps_postage_amount]
    ,[reseller_postage_amount]
    ,[cubic_pricing_flag]
    ,[destination_address]
    ,pe.recipient_address
    FROM ods.derived.v_reseller_prints_for_export t(NOLOCK)
    JOIN check_test c
    ON c.customer_id=t.customer_id
    JOIN ods.swsim.prints s(NOLOCK)
    ON t.postage_id=s.postage_id
    JOIN ods.postal.prints_extension pe(NOLOCK)
    on pe.postage_id=s.postage_id
    where t.customer_id IN (Select customer_id from #check)

    Hi Mark Subedi,
    In addtion to the above posts.
    The fragment referenced from the BOL
    You can create local and global temporary tables. Local temporary tables are visible only in the current session; global temporary tables are visible to all sessions.
    All local temporary tables are dropped automatically at the end of the current session.
    You can read more from the below link.
    https://technet.microsoft.com/en-us/library/aa258255(v=sql.80).aspx
    If you have any question, feel free to let me know.
    Eric Zhang
    TechNet Community Support

  • Pipelined Function with execute immediate

    Hello Experts,
    I have created a Pipe lined function with execute immediate, due to below requirement;
    1) Columns in where clause is passed dynamically.
    2) I want to know the data stored into above dynamic columns.
    3) I want to use it in report, so I don't want to insert it into a table.
    I have created a TYPE, then through execute immediate i have got the query and result of that query will be stored in TYPE.
    But when calling the function i am getting
    ORA-00932: inconsistent datatypes: expected - got -
    Below is my function and type, let me know i am going wrong, and is my logic correct.
    CREATE OR REPLACE TYPE OBJ_FPD AS OBJECT
                      (LOW_PLAN_NO VARCHAR2 (40),
                       FPD VARCHAR2 (5),
                       SERIAL_NO NUMBER,
                       CEDIA_CODE VARCHAR2 (2),
                       DT DATE);
    CREATE OR REPLACE TYPE FPD_TBL_TYPE AS TABLE OF OBJ_FPD;
    CREATE OR REPLACE FUNCTION FUNC_GET_FPD_DATE (P_LOW_PLAN_NO    VARCHAR2,
                                                  P_CEDIA_CODE     VARCHAR2,
                                                  P_SERIAL_NO      NUMBER)
       RETURN FPD_TBL_TYPE
       PIPELINED
    AS
       CURSOR C1
       IS
              SELECT 'FPD' || LEVEL TBL_COL
                FROM DUAL
          CONNECT BY LEVEL <= 31;
       V_STR        VARCHAR2 (5000);
       V_TBL_TYPE   FPD_TBL_TYPE;
    BEGIN
       FOR X IN C1
       LOOP
          V_STR :=
                'SELECT A.low_PLAN_NO,
               A.FPD,
               A.SERIAL_NO,
               A.cedia_code,
               TO_DATE (
                     SUBSTR (FPD, 4, 5)
                  || ''/''
                  || TO_CHAR (C.low_PLAN_PERIOD_FROM, ''MM'')
                  || ''/''
                  || TO_CHAR (C.low_PLAN_PERIOD_FROM, ''RRRR''),
                  ''DD/MM/RRRR'')
                  DT FROM ( SELECT low_PLAN_NO, '
             || ''''
             || X.TBL_COL
             || ''''
             || ' FPD, '
             || X.TBL_COL
             || ' SPTS, SERIAL_NO, cedia_code FROM M_low_PLAN_DETAILS WHERE NVL('
             || X.TBL_COL
             || ',0) > 0 AND SERIAL_NO = '
             || P_SERIAL_NO
             || ' AND cedia_code = '
             || ''''
             || P_CEDIA_CODE
             || ''''
             || ' AND low_PLAN_NO = '
             || ''''
             || P_LOW_PLAN_NO
             || ''''
             || ') A,
               M_low_PLAN_DETAILS B,
               M_low_PLAN_MSTR C
         WHERE     A.low_PLAN_NO = B.low_PLAN_NO
               AND A.cedia_code = B.cedia_code
               AND A.SERIAL_NO = B.SERIAL_NO
               AND B.low_PLAN_NO = C.low_PLAN_NO
               AND B.CLIENT_CODE = C.CLIENT_CODE
               AND B.VARIANT_CODE = C.VARIANT_CODE
    CONNECT BY LEVEL <= SPTS';
          EXECUTE IMMEDIATE V_STR INTO V_TBL_TYPE;
          FOR I IN 1 .. V_TBL_TYPE.COUNT
          LOOP
             PIPE ROW (OBJ_FPD (V_TBL_TYPE (I).LOW_PLAN_NO,
                                V_TBL_TYPE (I).FPD,
                                V_TBL_TYPE (I).SERIAL_NO,
                                V_TBL_TYPE (I).CEDIA_CODE,
                                V_TBL_TYPE (I).DT));
          END LOOP;
       END LOOP;
       RETURN;
    EXCEPTION
       WHEN OTHERS
       THEN
          RAISE_APPLICATION_ERROR (-20000, SQLCODE || ' ' || SQLERRM);
          RAISE;
    END;Waiting for your views.
    Regards,

    Ora Ash wrote:
    Hello Experts,
    I have created a Pipe lined function with execute immediate, due to below requirement;
    1) Columns in where clause is passed dynamically.No, that's something you've introduced, and is due to poor database design. You appear to have columns on your table called FPD1, FPD2 ... FPD31. The columns do not need to be 'passed dynamically'
    2) I want to know the data stored into above dynamic columns.And you can know the data without it being dynamic.
    3) I want to use it in report, so I don't want to insert it into a table.That's fine, though there's no reason to use a pipelined function.
    You also have an pointless exception handler, which masks any real errors.
    I'm not quite sure what the point of your "connect by" is in your query as we don't have your tables or data or know for sure what the expected output is.
    However, in terms of handling the 'dynamic' part that you've introduced, then you would be looking at doing something along the following lines, using a static query that requires no poor dynamic code, and no pipelined function...
    with x as (select level as dy from dual connect by level <= 31)
    select a.low_plan_no
          ,a.fpd
          ,a.serial_no
          ,a.cedia_code
          ,trunc(c.low_plan_period_from)+a.dy-1 as dt
    from  (select low_plan_no
                 ,dy
                 ,'FPD'||dy as fpd
                 ,spts
                 ,serial_no
                 ,cedia_code
           from (
                 select low_plan_no
                       ,x.dy
                       ,case x.dy when 1 then fpd1
                                  when 2 then fpd2
                                  when 3 then fpd3
                                  when 4 then fpd4
                                  when 5 then fpd5
                                  when 6 then fpd6
                                  when 7 then fpd7
                                  when 8 then fpd8
                                  when 9 then fpd9
                                  when 10 then fpd10
                                  when 11 then fpd11
                                  when 12 then fpd12
                                  when 13 then fpd13
                                  when 14 then fpd14
                                  when 15 then fpd15
                                  when 16 then fpd16
                                  when 17 then fpd17
                                  when 18 then fpd18
                                  when 19 then fpd19
                                  when 20 then fpd20
                                  when 21 then fpd21
                                  when 22 then fpd22
                                  when 23 then fpd23
                                  when 24 then fpd24
                                  when 25 then fpd25
                                  when 26 then fpd26
                                  when 27 then fpd27
                                  when 28 then fpd28
                                  when 29 then fpd29
                                  when 30 then fpd30
                                  when 31 then fpd31
                        else null
                        end as spts
                       ,serial_no
                       ,cedia_code
                 from   x cross join m_low_plan_details
                 where  serial_no = p_serial_no
                 and    cedia_code = p_cedia_code
                 and    low_plan_no = p_low_plan_no
           where  nvl(spts,0) > 0
          ) A
          join m_low_plan_details B on (    A.low_plan_no = B.low_plan_no
                                        and A.cedia_code = B.cedia_code
                                        and A.serial_no = B.serial_no
          join m_low_plan_mstr C on (    B.low_plan_no = C.low_plan_no
                                     and B.client_code = C.client_code
                                     and B.variant_code = C.variant_code
    connect by level <= spts;... so just remind us again why you think it needs to be dynamic?

  • EXECUTE IMMEDIATE ORA-01722 invalid number

    hi all
    i have a plsql procedure in which the following statement which gives this error ORA-01722: invalid number
    sql_stmt :='UPDATE Student set '||stu_gradefor||'=TO_NUMBER('||stu_marks||') where UserID='||stu_UID;
    EXECUTE IMMEDIATE sql_stmt;
    here all variables (stu_marks,stu_gradefor and stu_UID) are varchar2 coming from different procedure(form) but in the table named Student column HW1 (stu_gradefor) is of datatype number.
    I have tried a lot but could not make it to work. Is it that we cannot enter an number through EXECUTE IMMEDIATE? If Possible can somebody help me with this?
    Thanks a lot.
    Regards
    Jyoti

    create table Student(UserID varchar2(8) not null, HW1 number(3) , HW2 number(3) , PA1 number(3) , ................);
    create table Domain(R_Domain varchar2(11) not null, R_Status char(1) not null, R_Date Date null,R_Value varchar2(11) null, R_Mean varchar2(300) not null);
    insert into Domain( R_Domain, R_Status, R_Value, R_Mean )values(
         'Term','t','PA1','First Programming Assignment');
    Full names for HW1, HW2, PA1....are in the Domain table. so in variable stu_gradefor we get the R_Value.
    this is true :variable stu_marks is not actually a number, so the TO_NUMBER is causing the error. stu_marks is of datatype varchar2 but the field HW1,.. are all expecting a numeric value.
    i tried SELECT TO_NUMBER(stu_marks) INTO gmark FROM DUAL;
    sql_stmt :='UPDATE Student set '||stu_gradefor||'=(:1) where UserID='||stu_UID;
    EXECUTE IMMEDIATE sql_stmt using gmark;
    where gmark is a number but noting works.same error
    This can be true:the column userid is a varchar2 column with a mix of numeric and alpha numeric values. userid value that i inserted was'12345678'
    i there any other way to handle this situation?
    Thanks for replying
    Jyoti

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

  • 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

Maybe you are looking for