Skip to Main Content
  • Questions
  • Creating a table using Dynamic SQL in stored procedure get error ORA-00942

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Sanjoy.

Asked: August 11, 2003 - 3:58 pm UTC

Last updated: April 05, 2004 - 5:22 pm UTC

Version: 9.0.2

Viewed 10K+ times! This question is

You Asked

Tom,

I am using dynamic sql in my stored procedure to create a table 'A', the table table 'A' gets re-created every night in a batch job and may have additional columns depending on product attributes, therefore I have to drop the table and recreate it.
When I am running the script for the fist time the drop table statement gives me an error ORA-00942 table or view does not exist which is very obvious as the table is getting created for the first time and it does not exists.
I do not have control as the table get created based on product category, so every time a new product category gets created a new table has to be created. How do I manage this error is there a way I can check if the table does not exists I create the table first and do not try to drop the table. I do have DBA rights to the database.

my procedure looks like:
PROCEDURE SCP_test (STAGE_TABLE_DEFN IN VARCHAR2 )IS
v_sql LONG;
BEGIN
v_sql := 'DROP TABLE BK_STG_' || STAGE_TABLE_DEFN ||'';
DBMS_OUTPUT.PUT_LINE('v_sql: ' || v_sql);
EXECUTE IMMEDIATE v_sql;
v_sql := 'CREATE TABLE BK_STG_' || STAGE_TABLE_DEFN ||' AS SELECT * FROM STG_' || STAGE_TABLE_DEFN ||'';
DBMS_OUTPUT.PUT_LINE('v_sql: ' || v_sql);
EXECUTE IMMEDIATE v_sql;
EXCEPTION
WHEN others THEN
DBMS_OUTPUT.PUT_LINE('Validation Script SCP_STAGE_PRODUCT_CONFIGURATOR: failed at ERROR: ' || SQLCODE || SQLERRM);
END;

and Tom said...

ops$tkyte@ORA920> desc t
ERROR:
ORA-04043: object t does not exist


ops$tkyte@ORA920> declare
2 table_does_not_exist exception;
3 pragma exception_init( table_does_not_exist, -942 );
4 begin
5 begin
6 execute immediate 'drop table t';
7 exception
8 when table_does_not_exist
9 then NULL;
10 end;
11
12 execute immediate 'create table t ( x int )';
13 end;
14 /

PL/SQL procedure successfully completed.

ops$tkyte@ORA920> desc t
Name Null? Type
----------------------- -------- ----------------
X NUMBER(38)



a programming hint to take to heart.

It is true that 9,999 times out of 10,000 that a "WHEN OTHERS" exception handler that does not include "RAISE" in it -- is a bug.

All you have done is SILENTLY IGNORED an error. sure, you print out a pretty message -- but so what. the invoker gets "return code 0, all is well in the world".

I wish when others was "not supported". how many bugs I've seen cause people did not realize a low level routine actually failed -- the error was totally hidden.

don't do it!






Rating

  (6 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Sanjoy, August 11, 2003 - 4:34 pm UTC

Thanks Tom for your advice and a prompt response

Why 942 and not 4043 in exception_init????

DD, August 12, 2003 - 7:41 am UTC

ops$tkyte@ORA920> desc t
ERROR:
ORA-04043: object t does not exist


But then why did you use

pragma exception_init( table_does_not_exist, -942 );

Why did you use 942 and not 4043 for the exception init??
does a drop table which does not exist give 942??
I assume so but the first line was confusing.

Thanks
DD

Tom Kyte
August 12, 2003 - 8:56 am UTC

because a drop gives a 942.

the first line was there just to show you that T in fact did not exist so the exception handler MUST have been invoked, caught the exception and ignored it.

Sanjoy, August 12, 2003 - 11:21 am UTC

The above code works fine but when I use it in a loop I get error, here is how my proc looks like
CREATE OR REPLACE PROCEDURE SCP_TESTA IS
tmpVar NUMBER;
CURSOR stage_cursor is
SELECT stage_table, product_category, product_attribute
FROM pcm;
rec_stage_cursor stage_cursor%rowtype;
v_sql LONG;
table_does_not_exist exception;
pragma exception_init( table_does_not_exist, -942 );
BEGIN
tmpVar := 0;
OPEN stage_cursor;
LOOP
FETCH stage_cursor into rec_stage_cursor;
EXIT WHEN stage_cursor%NOTFOUND;
BEGIN
v_sql := 'SELECT count(*) into tmpVar FROM STG_' || rec_stage_cursor.stage_table ||'';
EXECUTE IMMEDIATE v_sql;
EXCEPTION
WHEN table_does_not_exist THEN
v_sql := 'CREATE TABLE STG_' || rec_stage_cursor.stage_table ||' AS SELECT sysdate dummy_date FROM dual';
EXECUTE IMMEDIATE v_sql;
END;
SCP_SPC ( rec_stage_cursor.stage_table, rec_stage_cursor.product_category, rec_stage_cursor.product_attribute );
DBMS_OUTPUT.PUT_LINE('EXECUTION OF PROC COMPLETED');
END LOOP;
END SCP_TESTA;
The compilation of the above works fine but at execution time I get the error
ERROR at line 1:
ORA-00905: missing keyword
ORA-06512: at "SYSADM.SCP_TESTA", line 18
ORA-06512: at line 2

Tom Kyte
August 12, 2003 - 11:30 am UTC

that is not how to do a select into using dynamic sql -- that is why.

Also, that is not the question you asked.  That is a horse of a totally different color.

This is how to do the above:

CREATE OR REPLACE PROCEDURE SCP_TESTA
as
    table_already_exists exception;
    pragma exception_init( table_already_exists, -955 );
BEGIN
    for x in (select stage_table, product_category, product_attribute from pcm)
    loop
        begin
            execute immediate 'create table stg_'||x.stage_table ||
                              ' as select sysdate dummy_date from dual';
        exception
            when table_already_exists then NULL;
        end;
        scp_spc( x.stage_table, x.product_category, x.product_attribute );
    end loop;
END SCP_TESTA;
/



and just fyi -- a select into using dynamic sql is:

ops$tkyte@ORA920> declare
  2          l_cnt number;
  3  begin
  4          execute immediate 'select count(*) from dual' INTO l_cnt;
  5  end;
  6  /

PL/SQL procedure successfully completed.



but here, doing a count(*) is pointless.
 

execute immediate and sql

Jerry, December 11, 2003 - 11:24 pm UTC

Can I run ddl using execute immediate together with other sq code?  I got errors when running:

SQL> begin
  2  execute immediate 'create table t (t1 integer)';
  3  delete from t;
  4  commit;
  5  end;
  6  /
delete from t;
            *
ERROR at line 3:
ORA-06550: line 3, column 13:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 3, column 1:
PL/SQL: SQL Statement ignored

However, if I remove the delete, it works.
SQL> begin
  2  execute immediate 'create table t (t1 integer)';
  3  end;
  4  /

PL/SQL procedure successfully completed.

Could you please help me understand this?  Thanks! 

Tom Kyte
December 13, 2003 - 10:36 am UTC

think about it -- when that block of code is compiled -- does T exist?

Nope.

Therefore, the block of code cannot possibly compile.

If you dynamically CREATE the table, you are forced to dynamically ACCESS the table.

Chicken and Egg problem here, you cannot compile the code because T does not exist so the static sql cannot be processed.

Great help

Jerry, December 13, 2003 - 6:11 pm UTC

Thanks so much for the explaination! It's great help!

HM, April 05, 2004 - 2:41 pm UTC

Tom,

What privileges does a user require to be able to do ddl using execute immediate? I am getting Insufficient privileges when trying to create view wihtin a stored procedure.


Tom Kyte
April 05, 2004 - 5:22 pm UTC

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library