sql >> Base de Datos >  >> RDS >> Oracle

¿Por qué no puedo usar variables de vinculación en declaraciones DDL/SCL en SQL dinámico?

Las variables de enlace no están permitidas en declaraciones DDL. Entonces, las siguientes declaraciones causarán errores:

  • Ejemplo n.º 1:instrucción DDL . Provocará ORA-01027:vincular variables no permitidas para operaciones de definición de datos

    EXECUTE IMMEDIATE
      'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT :def_val )'
      USING 42;
    
  • Ejemplo n.º 2:instrucción DDL . Causará ORA-00904::identificador no válido

    EXECUTE IMMEDIATE
      'CREATE TABLE dummy_table ( :col_name NUMBER )'
      USING var_col_name;
    
  • Ejemplo n.º 3:instrucción SCL . Provocará ORA-02248:opción no válida para ALTERAR SESIÓN

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

Problema

Para comprender por qué sucede esto, debemos ver cómo se procesan las declaraciones SQL dinámicas.

Normalmente, un programa de aplicación solicita al usuario el texto de una sentencia SQL y los valores de las variables del lenguaje principal utilizadas en la sentencia. Luego, Oracle analiza la declaración SQL. Es decir, Oracle examina la instrucción SQL para asegurarse de que sigue las reglas de sintaxis y se refiere a objetos de base de datos válidos. El análisis también implica verificar los derechos de acceso a la base de datos , reservar los recursos necesarios y encontrar la ruta de acceso óptima.

Énfasis agregado por el que responde

Tenga en cuenta que el paso de análisis ocurre antes vinculando cualquier variable a la declaración dinámica. Si examina los cuatro ejemplos anteriores, se dará cuenta de que no hay forma de que el analizador garantice la validez sintáctica de estas sentencias SQL dinámicas sin conocer los valores de las variables de vinculación.

  • Ejemplo #1 :Parser no puede saber si el valor de vinculación será válido. ¿Qué pasa si en lugar de USING 42 , el programador escribió USING 'forty-two' ?
  • Ejemplo #2 :El analizador no puede saber si :col_name sería un nombre de columna válido. ¿Qué pasaría si el nombre de la columna enlazada fuera 'identifier_that_well_exceeds_thirty_character_identifier_limit' ?
  • Ejemplo #3 :Valores para NLS_CALENDAR son constantes integradas (¿para una versión dada de Oracle?). El analizador no puede saber si la variable enlazada tendrá un valor válido.

Entonces, la respuesta es que no puede vincular elementos de esquema como nombres de tablas, nombres de columnas en SQL dinámico. Tampoco puede enlazar constantes integradas .

Solución

La única forma de lograr referencias dinámicas a elementos/constantes del esquema es usar la concatenación de cadenas en sentencias SQL dinámicas.

  • Ejemplo n.º 1:

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

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

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