Skip to Main Content
  • Questions
  • How to create a stored procedure only when a particular table exists

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, David.

Asked: April 20, 2017 - 6:51 pm UTC

Last updated: April 21, 2017 - 2:32 am UTC

Version: Oracle 12c

Viewed 1000+ times

You Asked

Hi Tom,

I'm trying to create a stored procedure only when a particular table already exists, using the following code:
SET SERVEROUTPUT ON

DECLARE
v_row_count INTEGER := 0;
e_wrong_db EXCEPTION;
BEGIN
SELECT count(*) INTO v_row_count
FROM all_objects
WHERE object_name = 'TABLE_A';

IF (v_row_count < 1) THEN
RAISE e_wrong_db;
ELSE
CREATE OR REPLACE PROCEDURE Create_report()
BEGIN
DBMS_OUTPUT.PUT_LINE('Fetch records and create the report.');
END Create_report;
END IF;
EXCEPTION
WHEN e_wrong_db THEN
DBMS_OUTPUT.PUT_LINE('>> ERROR: DB script not applicable.');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('other exceptions...');
RAISE;
END;

And I got the following error messages:
Error report -
ORA-06550: line 12, column 9:
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 <an identifier>
<a double-quoted delimited-identifier> <a bind variable> <<
continue close current delete fetch lock insert open rollback
savepoint set sql execute commit forall merge pipe purge
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.

Can you help me out?

Thanks,
David

and Connor said...

You cannot have DDL (create, alter, drop, etc) natively coded within a PL/SQL program. It can run

- plsql code
- sql code

so if you need to do something that is DDL, it must be passed over to the sql engine, using dynamic SQL. Here's a simple example:

SQL> create or replace
  2  procedure MY_PROC is
  3  begin
  4    --
  5    -- truncate is DDL
  6    --
  7    truncate table T;
  8  end;
  9  /

Warning: Procedure created with compilation errors.

SQL> sho err
Errors for PROCEDURE MY_PROC:

LINE/COL ERROR
-------- -----------------------------------------------------------------
6/12     PLS-00103: Encountered the symbol "TABLE" when expecting one of
         the following:
         := . ( @ % ;
         The symbol ":= was inserted before "TABLE" to continue.

SQL>
SQL> create or replace
  2  procedure MY_PROC is
  3  begin
  4    execute immediate 'truncate table T';
  5  end;
  6  /

Procedure created.

SQL>
SQL> exec my_proc;

PL/SQL procedure successfully completed.


So dynamic sql is needed for thoses case. But that doesnt mean you should go overboard, because dynamic SQL is only resolved at runtime, eg

SQL> create or replace
  2  procedure MY_PROC is
  3  begin
  4    execute immediate 'this is a piece of nonsense';
  5  end;
  6  /

Procedure created.


and hence debugging etc is harder.

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

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