DDL statements in PL/SQL?

17,066

Solution 1

I assume you're doing something like the following:

declare
   v_temp varchar2(20);
begin
   execute immediate 'create table temp(name varchar(20))';
   execute immediate 'insert into temp values(''XYZ'')';

   select name into v_name from temp;
end;

At compile time the table, TEMP, does not exist. It hasn't been created yet. As it doesn't exist you can't select from it; you therefore also have to do the SELECT dynamically. There isn't actually any need to do a SELECT in this particular situation though you can use the returning into syntax.

declare
   v_temp varchar2(20)
begin
   execute immediate 'create table temp(name varchar2(20))';
   execute immediate 'insert into temp 
                      values(''XYZ'')
                      returning name into :1'
                returning into v_temp;
end;

However, needing to dynamically create tables is normally an indication of a badly designed schema. It shouldn't really be necessary.

I can recommend René Nyffenegger's post "Why is dynamic SQL bad?" for reasons why you should avoid dynamic SQL, if at all possible, from a performance standpoint. Please also be aware that you are much more open to SQL injection and should use bind variables and DBMS_ASSERT to help guard against it.

Solution 2

If you run the program multiple time you will get an error even after modifying the program to run the select statement as dynamic SQL or using a returning into clause. Because when you run the program first time it will create the table without any issue but when you run it next time as the table already created first time and you don't have a drop statement it will cause an error: "Table already exists in the Database". So my suggestion is before creating a table in a pl/sql program always check if there is any table with the same name already exists in the database or not. You can do this check using a Data dictionary views /system tables which store the metadata depending on your database type.

For Example in Oracle you can use following views to decide if a tables needs to be created or not:

DBA_TABLES , ALL_TABLES, USER_TABLES

Share:
17,066
Aspirant
Author by

Aspirant

Updated on July 06, 2022

Comments

  • Aspirant
    Aspirant almost 2 years

    I am trying the code below to create a table in PL/SQL:

    DECLARE
        V_NAME VARCHAR2(20);
    BEGIN
        EXECUTE IMMEDIATE 'CREATE TABLE TEMP(NAME VARCHAR(20))';
        EXECUTE IMMEDIATE 'INSERT INTO TEMP VALUES(''XYZ'')';
        SELECT NAME INTO V_NAME FROM TEMP;
    END;
    /
    

    The SELECT statement fails with this error:

    PL/SQL: ORA-00942: table or view does not exist
    

    Is it possible to CREATE, INSERT and SELECT all in a single PL/SQL Block one after other?