EXECUTE IMMEDIATE - DDL

Can someone explain the reason for why oracle doesnt allow DDL statements to be executed directly in a PL/SQL block?

DDL statements execute an implicit commit before the statement is executed, and the statement itself is also automatically committed.
A pl/sql procedure typically should comprise one logical unit of work.
Both executing DDL and committing every individual record must be considered extreemly poor practice, resulting from brainwashing by the Evil Empire, aka Microsoft, where this is required because the concurrency model is completely different (and unelegant).
So, if you want to stop being a Ringwraith of Sauron, aka William H Gates III, or his amanuensis Saruman, aka Stephen Ballmer, please never ever issue DDL through a stored procedure.
Sybrand Bakker
Senior Oracle DBA

Similar Messages

  • Q? Correct way to EXECUTE IMMEDIATE DDL

    Hi All,
    So I'm a little surprised to find that there isn't a builtin feature to "ALTER TABLE x DISABLE ALL CONSTRAINTS". So I'm trying to write a procedure that does that:
    procedure change_local_constraints(p_tablename USER_TABLES.TABLE_NAME%TYPE,
    p_desired_status status_t,
    p_exception_clause exception_t DEFAULT NULL) as
    begin
    <<table_constraints>>
    FOR constraint_rec IN (SELECT constraint_name
    FROM user_constraints
    WHERE table_name = p_tablename
    AND status <> p_desired_status) LOOP
    execute immediate 'ALTER TABLE :i_table :i_status CONSTRAINT :i_constraint :i_exception_clause'
    using p_tablename, p_desired_status, constraint_rec.constraint_name, p_exception_clause;
    END LOOP table_constraints;
    end change_local_constraints;
    Note: that I've defined a couple of subtypes earlier in my package:
    SUBTYPE status_t IS VARCHAR2(10);
    SUBTYPE exception_t IS VARCHAR2(100);
    Note: the exception parameter is for an " EXCEPTIONS INTO MY_EXCEPTION_TABLE " clause.
    When I try to run this I get an error:
    ORA-00903: invalid table name
    I don't want to concatenate my SQL command together as that opens everything up to SQL Injection attacks. On the other hand, it appears that bind variables can't be used in this situation. Or perhaps in any DDL. Does anyone know of a way to do this or see an error in my code?
    Thanks,
    Steven

    1- Concatenating table and constraint name in your code is not going to pose any risk, becuase if table name is incorrect like 'XYZ; DROP TABLE T;' (fear of intejection), for loop will never execute. And your constraint name is coming from the loop.
    2- For p_desired_status you can verify before EXECUTE IMMEDIATE that it contains appropriate keyword only:
    IF p_desired_status NOT IN('ENABLE','DIABLE') THEN
    raise_application_error(-20100,'Invalid syntax');
    END IF;
    3- EXCEPTIONS INTO MY_EXCEPTION_TABLE will always be there, so there's no need to accept it in a parameter. And if it does not always have to be there, you can treat it like p_desired_status.
    Anwar

  • Problem wile EXECUTE IMMEDIATE DDL statement in procedure

    Hi ,
    This is my procedure and it's getting compiled but while executing procedure getting this error,
    can anyone please tell me how to fix this?
    create or replace procedure construct_Table (name_table IN VARCHAR2)
    IS
    v_tab_name varchar2(40):=NULL;
    v_sql_Stmt varchar2(32767) := NULL;
    finalquery varchar2(32767) :=NULL;
    cursor tp is
    select COLUMN_NAME,DATA_TYPE,DATA_PRECISION,CHAR_LENGTH  from all_tab_cols where table_name=name_table;
    BEGIN
    begin
    select TABLE_NAME into v_tab_name from user_tables where table_name=name_table;
    EXCEPTION
    WHEN no_Data_found
    THEN
    DBMS_OUTPUT.PUT_LINE('No such table exist');
    end;
    if(v_tab_name IS NOT NULL)then
    finalquery := 'CREATE TABLE '||v_tab_name||'_DUMMY (';
       FOR I IN tp LOOP
       if(I.data_type='VARCHAR2') then
       v_sql_stmt := finalquery ||I.column_name||' '||I.data_type||'('||I.char_length||') ';
       elsif(I.data_type='NUMBER') then
       v_sql_stmt := finalquery ||I.column_name||' '||I.data_type||'('||I.DATA_PRECISION ||') ';
       else
       v_sql_stmt := finalquery ||I.column_name||' '||I.data_type ;
       end if;
       finalquery := v_sql_stmt || ',';
       END LOOP;
       finalquery := SUBSTR(finalquery,1,LENGTH(finalquery) - 1)||')';
       dbms_output.put_line(finalquery);
       EXECUTE IMMEDIATE'grant create any table to cmsuser';
       EXECUTE IMMEDIATE finalquery;
    end if; 
    END;
    /This is the error I am getting
    Error starting at line 1 in command:
    begin
    construct_Table ('EMP');
    end;
    Error report:
    ORA-01031: insufficient privileges
    ORA-06512: at "CMSUSER.CONSTRUCT_TABLE", line 30
    ORA-06512: at line 2
    01031. 00000 -  "insufficient privileges"
    *Cause:    An attempt was made to change the current username or password
               without the appropriate privilege. This error also occurs if
               attempting to install a database without the necessary operating
               system privileges.
               When Trusted Oracle is configure in DBMS MAC, this error may occur
               if the user was granted the necessary privilege at a higher label
               than the current login.
    *Action:   Ask the database administrator to perform the operation or grant
               the required privileges.
               For Trusted Oracle users getting this error although granted the
               the appropriate privilege at a higher label, ask the database
               administrator to regrant the privilege at the appropriate label.Thanks ,
    Deekay.

    Deekay,
    If you grant create table privilege and create table in the same procedure, then how you will differentiate that which user you granted the privilege and in which schema, you are creating the table. Here, you are granting to "cmuser", but in the same schema, you are creating the table also. How can a user grant privilege to himself?
    Login as DBA, grant create any table privilege to "cmuser" from dba. Then, you can execute you procedure in "cmuser" schema.

  • Execute immediate on DDL command

    Below sample SQL is 1 of the many code that is running OK in our database. And this code has causes a lot of latch contention to our database and it's being called so many times that cause hard parse.
    /* test code */
    CREATE OR REPLACE PROCEDURE dsal (p_client_id NUMBER) IS
    BEGIN
    EXECUTE IMMEDIATE
    'create table tmp_dsal_'||p_client_id
    ' (client_id number, '||
    ' trade_id number, '||
    ' ps_id number, '||
    ' ps_liquid varchar2(2), '||
    ' status_code varchar2(3) default ''NA'' not null, '||
    ' start_value_dte date, '||
    ' end_value_dte date)';
    EXECUTE IMMEDIATE 'drop table tmp_dsal_'||p_client_id;
    END;
    I want to improve it by using bind variable. The below program compile with no error.
    CREATE OR REPLACE PROCEDURE dsal (p_client_id NUMBER) IS
    BEGIN
    EXECUTE IMMEDIATE
    'create table tmp_dsal_:client_id'||
    ' (client_id number, '||
    ' trade_id number, '||
    ' ps_id number, '||
    ' ps_liquid varchar2(2), '||
    ' status_code varchar2(3) default ''NA'' not null, '||
    ' start_value_dte date, '||
    ' end_value_dte date)' using p_client_id;
    EXECUTE IMMEDIATE 'drop table tmp_dsal_:client_id' using p_client_id;
    END;
    When I execute it, I'm getting the below error. I understand DML statement using bind variable in execute immediate command but not sure on DDL. Is there a workaround on issue or this is limitation?
    SQL> exec dsal(223);
    BEGIN dsal(223); END;
    ERROR at line 1:
    ORA-00922: missing or invalid option
    ORA-06512: at "SYS.DSAL", line 3
    ORA-06512: at line 1
    Appreciate any comment/help. Thanks

    Assuming that all of the client load processes run in seperate session, then do this once in the database and use this global temporary table for the loads. A GTT is a permanent object in the database, but the data it contains is only visible to the session that inserts it. Multiple sessions can access the same GTT at the same time, and will never see each other's data.
    CREATE TEMPORARY TABLE tmp_dsal (
       client_id       NUMBER,
       trade_id        NUMBER,
       ps_id           NUMBER,
       ps_liquid       VARCHAR2(2),
       status_code     VARCHAR2(3) DEFAULT 'NA' NOT NULL,
       start_value_dte DATE,
       end_value_dte   DATE)
    ON COMMIT [PRESERVE|DELETE] ROWSThe on commit clause determines what happens to the data in the GTT when the session that created the data issues a commit. DELETE will automaticall delete all of that session's data while PRESERVE will keep the data until the session either explicitly deletes it or the session ends.
    John

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

  • ORA-14552: cannot perform a DDL in a execute immediate - proc

    Hi All,
    I am trying to disable triggers in a stored procedure:
    PROCEDURE Alter_trigger_DISBALE
    IS
    BEGIN
         execute immediate ('alter trigger BEI_INS_MY DISABLE');
    END;
    I get the following error:
    ORA-14552: cannot perform a DDL, commit or rollback inside a query or DML
    Is there a solution for this problem ?
    Best Regards
    Friedhold

    How are you calling the procedure?
    I assume that, since your procedure actually compiles, it doesn't have the parenthesis around the EXCEUTE IMMEDIATE string and that there is a CREATE before the PROCEDURE. I hope that "disable" is spelled correctly in the real thing.
    Justin
    Distributed Database Consulting, Inc.
    http://www.ddbcinc.com/askDDBC

  • Executing multiple DDL statements with OracleCommand

    hi..
    im having trouble executing multiple ddl statements with the the oracle command object. i have tried to enclose them within Begin.. End; block but with no use.
    this problem seems to occur only with DDL statements,.. as my DML like update, delete and Inserts seem to work fine when enclosed within the PL /SQL block.
    single DDL statements also seem to work fine. so im guessing this has nothing to do with priviledges. any ideas?
    my code as follows
    OracleCommand command = new OracleCommand();
    command.CommandType = CommandType.Text;
    command.CommandText = string.Format(@"{0}",script);
    conn.Open();
    command.Connection = conn;
    command.ExecuteNonQuery();
    the script is read from a file, and looks like this. (note : i have removed any line breaks or any other characters)
    BEGIN ALTER TABLE SYSTEMUSER DISABLE CONSTRAINT FK_USER_CLIENT; ALTER TRIGGER SET_SUBSCRIPTION_SUB_I DISABLE; END;
    this is the error i get.
    Oracle.DataAccess.Client.OracleException: ORA-06550: line 1, column 7:
    PLS-00103: Encountered the symbol "ALTER" when expecting one of the following:
    begin case declare exit for goto if loop mod null pragma
    raise return select update while with <an identifier>
    <a double-quoted delimited-identifier> <a bind variable> <<
    close current delete fetch lock insert open rollback
    savepoint set sql execute commit forall merge pipe.

    If I'm not mistaken, we're not allowed to issue DDL inside anonymoue block (or stored procedure) since DDL has implicit commit in it. But you still can execute DDL using EXECUTE IMMEDIATE or using DBMS_SQL package. Try changing your CommandText like this,
    BEGIN
       EXECUTE IMMEDIATE 'ALTER TABLE SYSTEMUSER DISABLE CONSTRAINT FK_USER_CLIENT';
       EXECUTE IMMEDIATE 'ALTER TRIGGER SET_SUBSCRIPTION_SUB_I DISABLE';
    END;Hope this helps,
    [Nur Hidayat|http://nur-hidayat.net/]

  • Execute immediate on DBMS_METADATA.GET_DDL with error of ORA-01031: insufficient privileges

    I want to mirror a schema to a existing schema by creating DDL and recreate on the other schema with same name.
    I wrote the code below:
    create or replace
    PROCEDURE                                    SCHEMA_A."MAI__DWHMIRROR"
    AS
    v_sqlstatement CLOB:='bos';
    str varchar2(3999);
    BEGIN
      select
        replace(
          replace(replace(
          replace(DBMS_METADATA.GET_DDL('TABLE','XXXX','SCHEMA_A'),'(CLOB)',''),';','')
        ,'SCHEMA_A'
        ,'SCHEMA_B'
      into v_sqlstatement
      from dual;
      select  CAST(v_sqlstatement AS VARCHAR2(3999)) into str from dual;
      execute immediate ''||str;
    END;
    And Executing this block with below code:
    set serveroutput on
    begin
    SCHEMA_A.MAI__DWHMIRROR;
    end;
    But still getting the following error code:
    Error report:
    ORA-01031: insufficient privileges
    ORA-06512: at "SCHEMA_A.MAI__DWHMIRROR", line 47
    ORA-06512: at line 2
    01031. 00000 -  "insufficient privileges"
    *Cause:    An attempt was made to change the current username or password
               without the appropriate privilege. This error also occurs if
               attempting to install a database without the necessary operating
               system privileges.
               When Trusted Oracle is configure in DBMS MAC, this error may occur
               if the user was granted the necessary privilege at a higher label
               than the current login.
    *Action:   Ask the database administrator to perform the operation or grant
               the required privileges.
               For Trusted Oracle users getting this error although granted the
               the appropriate privilege at a higher label, ask the database
               administrator to regrant the privilege at the appropriate label.

    user5199319 wrote:
    USER has DBA Role
    when all  else fails Read The Fine Manual
    DBMS_METADATA

  • Execute Immediate in Oracle 10g

    Hi , I have a small doubt regarding execute immediate.
    As per my knowledge we use execute immediate for writing DDL(create,truncate,...) statements to execute in the procedure or function.
    But i have seen in my organization , some of the senior people(already left organization) used to write inserts , updates , deletes also in execute immediate even there is not much dynamic logic involved.
    But as per my knowledge execute immediate can be badly used by most of the hackers with SQL injection I guess!!!!!
    Is there any reason that they use execute immediate instead of writing the code directly??? Or is there any advantage in writing like this.???

    Using execute immediate to create tables and other DDL is fundamentally undesirable, and should be avoided at all cost.
    The use of execute immediate you seem to outline, should be avoided too. Apparently those seniors were unaware of the goal of PL/SQL and the disadvantage of execute immediate.
    If I could vote to remove execute immediate from PL/SQL, I would be immediately in favor, especially in packages, procedures and functions,as they are stored, which means pre-compiled.
    Sybrand Bakker
    Senior Oracle DBA

  • Using execute immediate in form

    hi all
    how can I use Execute Immediate In form It give me error but In sql no error
    thank you

    There are two options.
    1. FORMS DDL
    2. Call a backend function or procedure which has got EXECUTE_IMMEDIATE in it.
    Following procedure can be used to execute the dymanic sql in forms.
    Create this procedure in backend.
    CREATE OR REPLACE PROCEDURE pr_execute_immediate (p_sql_stmt VARCHAR2) IS
    BEGIN
    EXECUTE_IMMEDIATE(p_sql_stmt );
    END pr_execute_immediate;
    Edited by: Narayan H on Jun 2, 2010 4:00 AM
    Edited by: Narayan H on Jun 2, 2010 4:03 AM
    Edited by: Narayan H on Jun 2, 2010 4:05 AM

  • 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                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

  • Why or When should we use Execute Immediate in PLSQL??

    Hi Frnds,
    Long Ago i have received a interview question that ...
    How can U create a table in the PLSQL object(Function or procedure)?
    But the thing y should we use execute immediate?
    In which scenario we should we should use????????????
    Why or When should we use Execute Immediate in PLSQL????

    OR
    http://stackoverflow.com/questions/18375990/oracle-what-does-execute-immediate-means
    For DML you'd use it when running statements that you don't have available at compile time, e.g. if the column list is based on a selection from the user.
    In your case it's being used because DDL cannot be run as static SQL from within PL/SQL. Only certain query, DML and TCL commands are valid. Anything else has to be treated as dynamic.
    I'd say it's rare to need to use DDL from a PL/SQL block. TRUNCATE might be reasonable; if you find anything creating or dropping objects on the fly then that might be more of a concern as it can suggest a suboptimal data model.
    EXECUTE IMMEDIATE itself does not automatically commit; but if you execute DDL then that will behave the same as if you ran it outside PL/SQL, so it will commit in your case, yes.
    Incidentally, I'm not sure why your code is using an intermediate variable to hold the statement; that's useful if you want to display what it's going to run maybe, but you don't seem to be doing that. What you have could be done as:
    EXECUTE IMMEDIATE 'TRUNCATE TABLE BD_BIDS_EXT_DET';
    Thank you

  • Executing a DDL command without committing

    Hi!
    I have a PLSQL procedure that uses EXECUTE IMMEDIATE CREATE OR REPLACE DIRECTORY 'FROM_DIR' AS 'path' to obtain access to directories on the server. Before and after the statement is run, I have a list of inserts and updates into tables.
    When the statment is run, the database automatically issues a commit.
    I want to avoid the commit. Does anyone have a suggestion to how I can accomplish this. Is it perhaps possible to run the DDL statement in a separate session, thus avoiding the commit in my main session?

    This example should help you.
      1  DECLARE
      2  PROCEDURE MYTEST IS
      3  pragma autonomous_transaction;
      4  BEGIN
      5  EXECUTE IMMEDIATE 'CREATE TABLE TEST2(COL1 VARCHAR2(2))';
      6  END;
      7  BEGIN
      8  INSERT INTO test1(col1,col2) values(1,2);
      9  MYTEST;
    10  ROLLBACK;
    11* END;
    SQL> /
    PL/SQL procedure successfully completed.
    SQL>  select count(*) from test1;
      COUNT(*)
             0
    1 row selected.
    SQL> DESC TEST2
    Name                                      Null?    Type
    COL1                                               VARCHAR2(2)
    SQL> DROP TABLE TEST2;
    Table dropped.
    SQL> DECLARE
      2  PROCEDURE MYTEST IS
      3  pragma autonomous_transaction;
      4  BEGIN
      5  EXECUTE IMMEDIATE 'CREATE TABLE TEST2(COL1 VARCHAR2(2))';
      6  END;
      7  BEGIN
      8  INSERT INTO test1(col1,col2) values(1,2);
      9  MYTEST;
    10  COMMIT;
    11  END;
    12  /
    PL/SQL procedure successfully completed.
    SQL> select count(*) from test1;
      COUNT(*)
             1
    1 row selected.
    SQL>  DESC TEST2
    Name                                      Null?    Type
    COL1                                               VARCHAR2(2)

  • Delete From More than 1 table without using execute immediate

    Hi,
    Am new to PL/SQL, I had been asked to delete few of the table for my ETL jobs in Oracle 10G R2. I have to delete(truncate) few tables and the table names are in another table with a flag to delete it or not. So, when ever I run the job it should check for the flag and for those flag which is 'Y' then for all those tables should be deleted without using the Execute Immediate, because I dont have privilages to use "Execute Immediate" statement.
    Can anyone help me in how to do this.
    Regards
    Senthil

    Then tell you DBA's, or better yet their boss, that they need some additional training in how Oracle actually works.
    Yes, dynamic sql can be a bad thing when it is used to generate hundreds of identical queries that differ ony in the literals used in predicates, but for something like a set of delte table statements or truncate table statements, dynamic sql is no different in terms of the effect on the shared pool that hard coding the sql statements.
    This is a bad use of dynamic sql, because it generates a lot of nearly identical statements due to the lack of bind variables. It is the type of thing your DBA's should, correctly, bring out the lead pipe for.
    DECLARE
       l_sql VARCHAR2(4000);
    BEGIN
       FOR r in (SELECT account_no FROM accounts_to_delete) LOOP
          l_sql := 'DELETE FROM accounts WHERE account_no = '||r.account_no;
          EXECUTE IMMEDIATE l_sql;
       END LOOP;
    END;This will result in one sql statement in the shared pool for every row in accounts_to_delete. Although there is much else wrong with this example, from the bind variable perspective it should be re-written to use bind variables like:
    DECLARE
       l_sql  VARCHAR2(4000);
       l_acct NUMBER;
    BEGIN
       FOR r in (SELECT account_no FROM accounts_to_delete) LOOP
          l_sql := 'DELETE FROM accounts WHERE account_no = :b1';
          EXECUTE IMMEDIATE l_sql USING l_acct;
       END LOOP;
    END;However, since you cannot bind object names into sql statements, the difference in terms of the number of statements that end up in the shared pool between this:
    DECLARE
       l_sql VARCHAR2(4000);
    BEGIN
       FOR r in (SELECT table_name, delete_tab, trunc_tab
                 FROM tables_to_delete) LOOP
          IF r.delete_tab = 'Y' THEN
             l_sql := 'DELETE FROM '||r.table_name;
          ELSIF r.trunc_tab = 'Y' THEN
             l_sql := 'TRUNCATE TABLE '||r.table_name;
          ELSE
             l_sql := NULL;
          END IF;
          EXECUTE IMMEDIATE l_sql;
       END LOOP;
    END;and something like this:
    BEGIN
       DELETE FROM tab1;
       DELETE FROM tab2;
       EXECUTE IMMEDIATE 'TRUNCTE TABLE tab3';
    END;or this as a sql script
    DELETE FROM tab1;
    DELETE FROM tab2;
    TRUNCTE TABLE tab3;is absolutley nothing.
    Note that if you are truncating some of the tables, and wnat/need to use a stored procedure, you are going to have to use dynamic sql for the truncates anyway since trncate is ddl, and you cannot do ddl in pl/sql wiothout using dynamic sql.
    John

  • Regd:- Execute Immediate

    HI,
    WHEN I EXECUTE THE BELOW QUERY I get PLSQL /Numeric or value error. Suggestions are welcome.
    DECLARE
    CURSOR c1
    IS
    SELECT object_name, object_type, owner
    FROM all_objects
    WHERE object_type IN ('PACKAGE')
    AND object_name = 'PKG_UPLOAD'
    AND owner = 'TEST';
    lv_v_header VARCHAR2 (2000) := 'SELECT DBMS_METADATA.GET_DDL( ';
    lv_v_footer VARCHAR2 (200) := ' )FROM DUAL';
    lv_v_object_type all_objects.object_type%TYPE;
    lv_v_object_name all_objects.object_name%TYPE;
    lv_v_owner all_objects.owner%TYPE;
    lv_v_stmt VARCHAR2 (4000);
    lv_v_quotes VARCHAR2 (100) := '''';
    lv_v_comma VARCHAR2 (100) := ',';
    lv_v_value VARCHAR2 (32767);
    filehandler UTL_FILE.file_type;
    lv_v_file_name VARCHAR2 (3000);
    BEGIN
    FOR i IN c1
    LOOP
    BEGIN
    lv_v_file_name :=
    i.owner
    || '_'
    || i.object_name
    || CASE
    WHEN i.object_type = 'PACKAGE'
    THEN '.PKB'
    WHEN i.object_type = 'TRIGGER'
    THEN '.TRG'
    END;
    lv_v_object_type := i.object_type;
    lv_v_object_name := i.object_name;
    lv_v_owner := i.owner;
    lv_v_stmt :=
    lv_v_header
    || lv_v_quotes
    || lv_v_object_type
    || lv_v_quotes
    || lv_v_comma
    || lv_v_quotes
    || lv_v_object_name
    || lv_v_quotes
    || lv_v_comma
    || lv_v_quotes
    || lv_v_owner
    || lv_v_quotes
    || lv_v_footer;
    EXECUTE IMMEDIATE lv_v_stmt
    INTO lv_v_value;
    filehandler := UTL_FILE.fopen ('TEST_DIR', lv_v_file_name, 'w');
    UTL_FILE.putf (filehandler, lv_v_value||'\n');
    UTL_FILE.fclose (filehandler);
    END;
    END LOOP;
    END;
    /

    In case you need help to use UTL_FILE, then here it is.
    SQL> DECLARE
      2    myddl clob;
      3    fname VARCHAR2(200);
      4    extn VARCHAR2(200);
      5 
      6  /* Main function to get the DDls with DBMS_METADATA */ 
      7    FUNCTION get_metadata(pi_obj_name  dba_objects.object_name%TYPE,
      8                          pi_obj_type  IN dba_objects.object_type%TYPE,
      9                          pi_obj_owner IN dba_objects.owner%TYPE) RETURN clob IS
    10      h   number;
    11      th  number;
    12      doc clob;
    13    BEGIN
    14      h := DBMS_METADATA.open(pi_obj_type);
    15      DBMS_METADATA.set_filter(h, 'SCHEMA', pi_obj_owner);
    16      DBMS_METADATA.set_filter(h, 'NAME', pi_obj_name);
    17      th := DBMS_METADATA.add_transform(h, 'MODIFY');
    18      th := DBMS_METADATA.add_transform(h, 'DDL');
    19      --DBMS_METADATA.set_transform_param(th,'SEGMENT_ATTRIBUTES',false);
    20      doc := DBMS_METADATA.fetch_clob(h);
    21      DBMS_METADATA.CLOSE(h);
    22      RETURN doc;
    23    END get_metadata;
    24 
    25  ---Writing the CLOB using UTL_FILE
    26  PROCEDURE write_clob(p_clob in clob, pi_fname VARCHAR2) as
    27      l_offset number default 1;
    28      fhandle UTL_FILE.file_type;
    29      buffer VARCHAR2(4000);
    30    BEGIN
    31      fhandle:=UTL_FILE.fopen('SAUBHIK',pi_fname,'A');
    32      loop
    33        exit when l_offset > dbms_lob.getlength(p_clob);
    34        buffer:=dbms_lob.substr(p_clob, 255, l_offset);
    35        UTL_FILE.put_line(fhandle,buffer);
    36        l_offset := l_offset + 255;
    37        buffer:=NULL;
    38      end loop;
    39      UTL_FILE.fclose(fhandle);
    40    END write_clob; 
    41 
    42  ---Main execution begins. 
    43  BEGIN
    44    FOR i in (SELECT object_name, object_type, owner
    45                FROM dba_objects
    46               WHERE owner IN ('SCOTT', 'HR')
    47                 AND object_type IN ('PACKAGE', 'TRIGGER')) LOOP
    48      --Calling the function.              
    49      myddl := get_metadata(i.object_name,i.object_type,i.owner);
    50      --Preparing the filename.
    51      fname := i.owner||i.object_name || '.' ||
    52               CASE WHEN i.object_type='PACKAGE' THEN 'pkb'
    53               ELSE 'trg'
    54               END;
    55     --Writing the file using UTL_FILE.
    56      write_clob(myddl,fname);
    57    END LOOP;
    58  END;
    59  /
    PL/SQL procedure successfully completed.
    SQL> also, about your error, "EXECUTE IMMEDIATE lv_v_stmt INTO lv_v_value;" DBMS_METADATA.get_dll returns a CLOB.

Maybe you are looking for

  • How to add a  member in planning deleting the old one ?

    Hi All, We are loading metadata in Hyperion planning through ODI. As the part of metadata, we are also loading the UDAs by defining certain logic in ODI.We have a requirement where we want to update UDAs in some members as well as remove the old UDAs

  • ALV Report to display the status of the requests raised through ESS

    Hi All, We have to develop a ALV report to display the status of the requests raised through ESS for Leave, Travel & Event Management, Travel and Appraisal workflows. ESS Travel, ESS TEM, ESS Apraisal workflows are associted with SAP Business Objects

  • BAPI for changing parked documents

    Hi , I need to know any BAPI exist for changing the posting date of the parked documents. Please let me know if there are any BAPI's Thanks

  • Invoke process from string value

    Hi all, I am trying to create a monitoring process that should monitor a mailbox. This monitoring process should look in the subject of the individual mails and by the subject determine which action to take (which underlying process) that should be i

  • Sharing Address Book with e-mail only accounts

    Hello: I have created two email only account and would like to share the primary address book with these accounts. I have added these accounts in sharing folders and sent the invite. The main functionality I am looking for is access my contact inform