ventajas query immediate ejemplo dinamicos dinamico cursores oracle plsql dynamic-sql execute-immediate

oracle - query - pl sql ventajas



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

Estoy tratando de ejecutar un comando SQL dentro de SQL dinámico con variables de vinculación:

-- 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;

Luego, en el lado del cliente, intento invocar el procedimiento:

Test_Pkg.Set_Nls_Calendar(''Thai Buddha'');

Pero esto me da ORA-02248: invalid option for ALTER SESSION .

Y mi pregunta es: ¿por qué no puedo usar variables de vinculación en las sentencias DDL / SCL en SQL dinámico?


Las variables de vinculación no están permitidas en las sentencias DDL. Entonces las siguientes declaraciones causarán errores:

Problema

Para entender por qué sucede esto, necesitamos ver cómo se procesan las sentencias SQL dinámicas .

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

1 Énfasis añadido por el que responde

Tenga en cuenta que el paso de análisis ocurre antes de vincular las variables 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 de SQL dinámico sin conocer los valores de las variables de vinculación.

  • Ejemplo n. ° 1 : El analizador no puede decir si el valor de vinculación será válido. ¿Qué ocurre si en lugar de USING 42 , el programador escribe USING ''forty-two'' ?
  • Ejemplo # 2 : El analizador no puede decir si :col_name sería un nombre de columna válido. ¿Qué ocurre si el nombre de la columna dependiente es ''identifier_that_well_exceeds_thirty_character_identifier_limit'' ?
  • Ejemplo # 3 : los valores para NLS_CALENDAR están integrados en constantes (para una versión de Oracle dada?). El analizador no puede decir si la variable enlazada tendrá un valor válido.

Entonces, la respuesta es que no puede vincular elementos de esquema como nombres de tabla, nombres de columna en SQL dinámico. Tampoco puedes unir las constantes integradas .

Solución

La única forma de lograr referencias de elementos / constantes de esquema dinámicamente es utilizar concatenación de cadenas en sentencias SQL dinámicas.

  • Ejemplo 1:

    EXECUTE IMMEDIATE ''CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT '' || to_char(42) || '')'';

  • Ejemplo # 2:

    EXECUTE IMMEDIATE ''CREATE TABLE dummy_table ('' || var_col_name || '' NUMBER )'';

  • Ejemplo n. ° 3:

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