Променливите за свързване не са разрешени в DDL изразите. Така че следните изрази ще причинят грешки:
-
Пример №1:DDL израз . Ще предизвика ORA-01027:свързващи променливи не са разрешени за операции по дефиниране на данни
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT :def_val )' USING 42;
-
Пример №2:DDL израз . Ще причини ORA-00904::невалиден идентификатор
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( :col_name NUMBER )' USING var_col_name;
-
Пример №3:SCL изявление . Ще предизвика ORA-02248:невалидна опция за ALTER SESSION
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_CALENDAR = :cal' USING var_calendar_option;
Проблем
За да разберем защо това се случва, трябва да разгледаме как се обработват динамичните SQL изрази.
Обикновено приложната програма подканва потребителя за текста на SQL израз и стойностите на хост променливите, използвани в оператора. След това Oracle анализира SQL израза. Тоест Oracle проверява SQL израза, за да се увери, че той следва синтактични правила и се отнася до валидни обекти на база данни. Разборът включва и проверка на правата за достъп до база даннита , запазване на необходимите ресурси и намиране на оптималния път за достъп.
Ударение, добавено от отговарящия
Имайте предвид, че стъпката за синтактичен анализ се случва преди обвързване на всякакви променливи към динамичния израз. Ако разгледате горните четири примера, ще разберете, че няма начин анализаторът да гарантира синтактичната валидност на тези динамични SQL изрази, без да знае стойностите за свързващите променливи.
- Пример №1 :Парсерът не може да каже дали стойността на свързване ще бъде валидна. Ами ако вместо
USING 42
, написа програмистUSING 'forty-two'
? - Пример №2 :Парсерът не може да разбере дали
:col_name
ще бъде валидно име на колона. Ами ако името на обвързаната колона беше'identifier_that_well_exceeds_thirty_character_identifier_limit'
? - Пример №3 :Стойности за
NLS_CALENDAR
са вградени в константи (за дадена версия на Oracle?). Парсерът не може да каже дали свързаната променлива ще има валидна стойност.
Така че отговорът е, че не можете да свързвате елементи на схемата като имена на таблици, имена на колони в динамичен SQL. Нито можете да свързвате вградени константии .
Решение
Единственият начин да постигнете динамично препращане към елементи/константи на схемата е да използвате конкатенация на низове в динамични SQL изрази.
-
Пример №1:
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT ' || to_char(42) || ')';
-
Пример №2:
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table (' || var_col_name || ' NUMBER )';
-
Пример №3:
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_CALENDAR = ''' || var_calendar_option || '''';