Reputation: 543
I am using Oracle SQL Developer.
I have an anonymous block that drops a table if it exists.
I don't have permission to create procedures or functions, so I have to call the anonymous block repeatedly.
To simplify things, I would like to store the names of all the affected tables in variables at the beginning of my script, and then refer to the appropriate variables later.
DEFINE v_InputTable = 'Table Name';
DECLARE
InputTable VARCHAR2(80) := &v_InputTable;
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE ' || InputTable;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
/
When I try this, I get an error "PLS-00103: Encountered the symbol "TABLE" when expecting one of the following:..."
Can someone please explain what I am doing wrong.
Upvotes: 0
Views: 1341
Reputation: 191570
Substitution variables are replaced in a fairly simplistic way. You have to enclose your references to strings within single quotes, where they become a literal. Instead of what you have, that becomes:
DECLARE
InputTable VARCHAR2(80) := '&v_InputTable';
You don't really need the PL/SQL variable here, you can use the substitution variable directly in the dynamic statement (still within a quoted string):
DEFINE v_InputTable = 'Table Name';
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE &v_InputTable';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
END;
/
You can also define a bind variable with the variable
command, rather than define
, but for this usage a substitution is probably simpler.
You could run that drop comand statically as plain SQL of course, but I guess you want to hide the table-not-found error.
The error suggests your defined value is actually literally 'Table Name
', which is an invalid name anyway unless you treat it as a quoted identifier - and it's really better not to do that. But if you must, or are playing around to see how they work, remember the case is fixed too, and every reference to it has to be identical and quoted. If you are trying to drop (and then recreate?) a table with a space in the name, you'd need to wrap the value in double quotes:
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE "&v_InputTable"';
... or if you want a separate variable and concatenate the dynamic statement:
DECLARE
InputTable VARCHAR2(80) := '"&v_InputTable"';
Upvotes: 1