Oracle
 sql >> база данни >  >> RDS >> Oracle

Защо не мога да използвам променливи за свързване в DDL/SCL изрази в динамичен SQL?

Променливите за свързване не са разрешени в 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 || '''';
    



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Разлика между времеви печати в милисекунди в Oracle

  2. Параметър за изчакване на IDLE в Oracle

  3. MS Достъп до Oracle лесно преобразуване / миграция

  4. Как да получите века от дата в Oracle

  5. Как да проверите пространството за таблици в Oracle SQL Developer?