Bindvariabelen zijn niet toegestaan in DDL-instructies. De volgende uitspraken zullen dus fouten veroorzaken:
-
Voorbeeld #1:DDL-statement . Zal ORA-01027 veroorzaken:bindvariabelen niet toegestaan voor bewerkingen voor gegevensdefinitie
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT :def_val )' USING 42;
-
Voorbeeld #2:DDL-statement . Zal leiden tot ORA-00904::ongeldige identifier
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( :col_name NUMBER )' USING var_col_name;
-
Voorbeeld #3:SCL-statement . Zal leiden tot ORA-02248:ongeldige optie voor ALTER SESSIE
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_CALENDAR = :cal' USING var_calendar_option;
Probleem
Om te begrijpen waarom dit gebeurt, moeten we kijken naar hoe dynamische SQL-statements worden verwerkt.
Gewoonlijk vraagt een toepassingsprogramma de gebruiker om de tekst van een SQL-instructie en de waarden van hostvariabelen die in de instructie worden gebruikt. Vervolgens parseert Oracle de SQL-instructie. Dat wil zeggen, Oracle onderzoekt de SQL-instructie om er zeker van te zijn dat deze de syntaxisregels volgt en verwijst naar geldige database-objecten. Parsing omvat ook het controleren van databasetoegangsrechten , het reserveren van de benodigde middelen en het vinden van het optimale toegangspad.
Nadruk toegevoegd door beantwoorder
Merk op dat de parseerstap vóór . plaatsvindt het binden van variabelen aan de dynamische instructie. Als u de bovenstaande vier voorbeelden bekijkt, zult u zich realiseren dat de parser op geen enkele manier de syntactische geldigheid van deze dynamische SQL-instructies kan garanderen zonder de waarden voor bindvariabelen te kennen.
- Voorbeeld #1 :Parser kan niet zeggen of de bindwaarde geldig is. Wat als in plaats van
USING 42
, programmeur schreefUSING 'forty-two'
? - Voorbeeld #2 :Parser kan niet zien of
:col_name
zou een geldige kolomnaam zijn. Wat als de afhankelijke kolomnaam'identifier_that_well_exceeds_thirty_character_identifier_limit'
was ? - Voorbeeld #3 :Waarden voor
NLS_CALENDAR
zijn ingebouwd in constanten (voor een bepaalde Oracle-versie?). Parser kan niet zeggen of de gebonden variabele een geldige waarde zal hebben.
Het antwoord is dus dat u geen schema-elementen zoals tabelnamen, kolomnamen in dynamische SQL kunt binden. Je kunt ook geen ingebouwde constanten binden .
Oplossing
De enige manier om dynamisch naar schema-elementen/constanten te verwijzen, is door tekenreeksen te gebruiken in dynamische SQL-instructies.
-
Voorbeeld #1:
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT ' || to_char(42) || ')';
-
Voorbeeld #2:
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table (' || var_col_name || ' NUMBER )';
-
Voorbeeld #3:
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_CALENDAR = ''' || var_calendar_option || '''';