Bindevariablen sind in DDL-Anweisungen nicht zulässig. Die folgenden Anweisungen verursachen also Fehler:
-
Beispiel Nr. 1:DDL-Anweisung . Verursacht ORA-01027:Bindevariablen sind für Datendefinitionsoperationen nicht zulässig
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT :def_val )' USING 42;
-
Beispiel #2:DDL-Anweisung . Verursacht ORA-00904::ungültige Kennung
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( :col_name NUMBER )' USING var_col_name;
-
Beispiel #3:SCL-Anweisung . Verursacht ORA-02248:ungültige Option für ALTER SESSION
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_CALENDAR = :cal' USING var_calendar_option;
Problem
Um zu verstehen, warum dies geschieht, müssen wir uns ansehen, wie dynamische SQL-Anweisungen verarbeitet werden.
Typischerweise fordert ein Anwendungsprogramm den Benutzer auf, den Text einer SQL-Anweisung und die Werte der in der Anweisung verwendeten Host-Variablen einzugeben. Dann analysiert Oracle die SQL-Anweisung. Das heißt, Oracle untersucht die SQL-Anweisung, um sicherzustellen, dass sie den Syntaxregeln folgt und auf gültige Datenbankobjekte verweist. Beim Parsing werden auch die Zugriffsrechte der Datenbank geprüft , benötigte Ressourcen reservieren und den optimalen Zugriffspfad finden.
Hervorhebung durch Antworter hinzugefügt
Beachten Sie, dass der Parsing-Schritt vorher stattfindet Binden beliebiger Variablen an die dynamische Anweisung. Wenn Sie die obigen vier Beispiele untersuchen, werden Sie feststellen, dass es für den Parser keine Möglichkeit gibt, die syntaktische Gültigkeit dieser dynamischen SQL-Anweisungen zu garantieren, ohne die Werte für Bindevariablen zu kennen.
- Beispiel Nr. 1 :Parser kann nicht sagen, ob der Bindungswert gültig ist. Was wäre, wenn statt
USING 42
, Programmierer schriebUSING 'forty-two'
? - Beispiel Nr. 2 :Parser kann nicht erkennen, ob
:col_name
wäre ein gültiger Spaltenname. Was wäre, wenn der Name der gebundenen Spalte'identifier_that_well_exceeds_thirty_character_identifier_limit'
wäre ? - Beispiel Nr. 3 :Werte für
NLS_CALENDAR
sind eingebaute Konstanten (für eine bestimmte Oracle-Version?). Parser kann nicht sagen, ob die gebundene Variable einen gültigen Wert haben wird.
Die Antwort ist also, dass Sie keine Schemaelemente wie Tabellennamen oder Spaltennamen in dynamischem SQL binden können. Sie können auch keine eingebauten Konstanten binden .
Lösung
Die einzige Möglichkeit, Schemaelemente/Konstanten dynamisch zu referenzieren, ist die Verwendung von Zeichenfolgenverkettungen in dynamischen SQL-Anweisungen.
-
Beispiel Nr. 1:
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT ' || to_char(42) || ')';
-
Beispiel Nr. 2:
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table (' || var_col_name || ' NUMBER )';
-
Beispiel #3:
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_CALENDAR = ''' || var_calendar_option || '''';