4
votes

When I run this query

DECLARE
      num NUMBER;
BEGIN

    SELECT COUNT(*) INTO num FROM user_all_tables WHERE TABLE_NAME=upper('DatabaseScriptLog')
    ;

    IF num < 1 THEN

      CREATE TABLE DatabaseScriptLog 
      (ScriptIdentifier VARCHAR(100) NOT NULL,
       ScriptType VARCHAR(50), 
       StartDate TIMESTAMP, 
       EndDate TIMESTAMP, 
       PRIMARY KEY (ScriptIdentifier)
       );

    END IF;

END;

When execute the above, I got the following:

PLS-00103: Encountered the symbol "CREATE" when expecting one of the following:

begin case declare exit for goto if loop mod null pragma raise return select update while with << close current delete fetch lock insert open rollback
savepoint set sql execute commit forall merge pipe 06550. 00000 - "line %s, column %s:\n%s" *Cause: Usually a PL/SQL compilation error.

2
What is your question? "What does this error mean?", "Does this mean I can't create a table inside a conditional?", "How should I do this instead?", etc. Thanks!Devin Burke

2 Answers

10
votes

You cannot run DDL statements like that. You need to use dynamic SQL (EXECUTE IMMEDIATE).

IF num < 1 THEN

  EXECUTE IMMEDIATE 'CREATE TABLE DatabaseScriptLog (ScriptIdentifier VARCHAR(100) NOT NULL, ScriptType VARCHAR(50), StartDate TIMESTAMP, EndDate TIMESTAMP, PRIMARY KEY (ScriptIdentifier))'

END IF;
0
votes

You cannot do this like you could in SQLServer. You need to execute the create code through a stored procedure that is already in the proper schema. You pass the create code as a parameter and the stored procedure that has the correct privileges does it for you.

I use a version script that updates the schema to the latest by running schema altering operations separated by if-then clauses to check what version the db is at. After altering it increments the version so that the next if statements test passes and so on. If you are up to date and run the script the ifs skip all altering code. If your db is at version 46 and you run the script which has all changes up to 50, you execute only the blocks that represent versions 47-50.

You could execute immediate but would need elevated privileges which I would not recommend.

Hope this helps.