Oracle
 sql >> Database >  >> RDS >> Oracle

Perché non posso utilizzare le variabili di collegamento nelle istruzioni DDL/SCL in SQL dinamico?

Le variabili di associazione non sono consentite nelle istruzioni DDL. Quindi le seguenti affermazioni causeranno errori:

  • Esempio n. 1:istruzione DDL . Causerà ORA-01027:associazione di variabili non consentite per operazioni di definizione dei dati

    EXECUTE IMMEDIATE
      'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT :def_val )'
      USING 42;
    
  • Esempio n. 2:istruzione DDL . Causerà ORA-00904::identificatore non valido

    EXECUTE IMMEDIATE
      'CREATE TABLE dummy_table ( :col_name NUMBER )'
      USING var_col_name;
    
  • Esempio n. 3:istruzione SCL . Causerà ORA-02248:opzione non valida per ALTER SESSION

    EXECUTE IMMEDIATE
      'ALTER SESSION SET NLS_CALENDAR = :cal'
      USING var_calendar_option;
    

Problema

Per capire perché ciò accade, dobbiamo guardare come vengono elaborate le istruzioni SQL dinamiche.

In genere, un programma applicativo richiede all'utente il testo di un'istruzione SQL ei valori delle variabili host utilizzate nell'istruzione. Quindi Oracle analizza l'istruzione SQL. Ovvero, Oracle esamina l'istruzione SQL per assicurarsi che segua le regole di sintassi e si riferisce a oggetti di database validi. L'analisi implica anche la verifica dei diritti di accesso al database , riservando le risorse necessarie e trovando il percorso di accesso ottimale.

Enfasi aggiunta dal risponditore

Tieni presente che il passaggio di analisi avviene prima vincolare qualsiasi variabile all'istruzione dinamica. Se esamini i quattro esempi precedenti, ti renderai conto che non c'è modo per il parser di garantire la validità sintattica di queste istruzioni SQL dinamiche senza conoscere i valori per le variabili di binding.

  • Esempio n. 1 :Il parser non può dire se il valore di collegamento sarà valido. E se invece di USING 42 , il programmatore ha scritto USING 'forty-two' ?
  • Esempio n. 2 :Il parser non può dire se :col_name sarebbe un nome di colonna valido. E se il nome della colonna associata fosse 'identifier_that_well_exceeds_thirty_character_identifier_limit' ?
  • Esempio n. 3 :valori per NLS_CALENDAR sono integrate costanti (per una determinata versione di Oracle?). Il parser non può dire se la variabile associata avrà un valore valido.

Quindi la risposta è che non è possibile associare elementi dello schema come nomi di tabelle, nomi di colonne in SQL dinamico. Né puoi associare costanti integrate .

Soluzione

L'unico modo per ottenere un riferimento dinamico a elementi/costanti dello schema è utilizzare la concatenazione di stringhe nelle istruzioni SQL dinamiche.

  • Esempio n. 1:

    EXECUTE IMMEDIATE
      'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT ' || to_char(42) || ')';
    
  • Esempio n. 2:

    EXECUTE IMMEDIATE
      'CREATE TABLE dummy_table (' || var_col_name || ' NUMBER )';
    
  • Esempio n. 3:

    EXECUTE IMMEDIATE
      'ALTER SESSION SET NLS_CALENDAR = ''' || var_calendar_option || '''';