Zmienne wiązania nie są dozwolone w instrukcjach DDL. Dlatego następujące stwierdzenia spowodują błędy:
-
Przykład 1:oświadczenie DDL . Spowoduje ORA-01027:wiązanie zmiennych nie jest dozwolone dla operacji definiowania danych
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT :def_val )' USING 42;
-
Przykład nr 2:oświadczenie DDL . Spowoduje ORA-00904::nieprawidłowy identyfikator
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( :col_name NUMBER )' USING var_col_name;
-
Przykład 3:oświadczenie SCL . Spowoduje ORA-02248:nieprawidłowa opcja dla ZMIANY SESJI
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_CALENDAR = :cal' USING var_calendar_option;
Problem
Aby zrozumieć, dlaczego tak się dzieje, musimy przyjrzeć się, jak przetwarzane są dynamiczne instrukcje SQL.
Zazwyczaj aplikacja pyta użytkownika o tekst instrukcji SQL i wartości zmiennych języka bazowego użytych w instrukcji. Następnie Oracle analizuje instrukcję SQL. Oznacza to, że Oracle sprawdza instrukcję SQL, aby upewnić się, że jest ona zgodna z regułami składni i odwołuje się do prawidłowych obiektów bazy danych. Parsowanie obejmuje również sprawdzanie praw dostępu do bazy danych , rezerwując potrzebne zasoby i znajdując optymalną ścieżkę dostępu.
Podkreślenie dodane przez osobę odpowiedzialną
Pamiętaj, że krok parsowania ma miejsce przed powiązanie dowolnych zmiennych z instrukcją dynamic. Jeśli przeanalizujesz powyższe cztery przykłady, zdasz sobie sprawę, że parser nie może zagwarantować poprawności składniowej tych dynamicznych instrukcji SQL bez znajomości wartości zmiennych wiązanych.
- Przykład nr 1 :Parser nie może stwierdzić, czy wartość wiązania będzie prawidłowa. Co jeśli zamiast
USING 42
, programista napisałUSING 'forty-two'
? - Przykład nr 2 :Parser nie może stwierdzić, czy
:col_name
byłaby prawidłową nazwą kolumny. Co się stanie, jeśli powiązana nazwa kolumny to'identifier_that_well_exceeds_thirty_character_identifier_limit'
? - Przykład #3 :Wartości dla
NLS_CALENDAR
są wbudowane w stałe (dla danej wersji Oracle?). Parser nie może stwierdzić, czy powiązana zmienna będzie miała prawidłową wartość.
Odpowiedź brzmi:nie można powiązać elementów schematu, takich jak nazwy tabel, nazwy kolumn w dynamicznym SQL. Nie możesz też powiązać wbudowanych stałych .
Rozwiązanie
Jedynym sposobem na dynamiczne odwoływanie się do elementów/stałych schematu jest użycie konkatenacji ciągów w dynamicznych instrukcjach SQL.
-
Przykład nr 1:
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT ' || to_char(42) || ')';
-
Przykład nr 2:
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table (' || var_col_name || ' NUMBER )';
-
Przykład #3:
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_CALENDAR = ''' || var_calendar_option || '''';