Почему я не могу использовать переменные привязки в операторах DDL/SCL в динамическом SQL?

Я пытаюсь выполнить команду SQL в динамическом SQL с переменными bind:

-- this procedure is a part of PL/SQL package Test_Pkg
PROCEDURE Set_Nls_Calendar(calendar_ IN VARCHAR2)
IS
BEGIN
   EXECUTE IMMEDIATE
      'ALTER SESSION
      SET NLS_CALENDAR = :cal'
      USING IN calendar_;
END Set_Nls_Calendar;

затем на стороне клиента, я пытаюсь вызвать процедуру:

Test_Pkg.Set_Nls_Calendar('Thai Buddha');

но это get's me ORA-02248: invalid option for ALTER SESSION.

и мой вопрос: почему я не могу использовать переменные привязки в операторах DDL/SCL в динамическом SQL?

1 ответов


переменные привязки не разрешены в инструкциях DDL. Таким образом, следующие утверждения вызовут ошибки:

чтобы понять, почему это происходит, нам нужно посмотреть на как обрабатываются динамические операторы SQL.

обычно прикладная программа запрашивает у пользователя текст SQL оператор и значения переменных хоста, используемые в операторе. Затем Oracle анализирует инструкцию SQL. То есть Oracle проверяет инструкцию SQL, чтобы убедиться, что она следует правилам синтаксиса и относится к допустимым объектам базы данных. Синтаксический анализ также включает проверку прав доступа к базе данных1, резервирования необходимых ресурсов и поиск оптимального пути доступа.

1выделено ответчик!--62-->

обратите внимание, что шаг разбора происходит до привязка любых переменных к динамическому оператору. Если вы изучите приведенные выше четыре примера, вы поймете, что синтаксический анализатор не может гарантировать синтаксическую валидность этих динамических операторов 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 || '''';