¿Por qué no podemos escribir la declaración ddl directamente en el bloque PL / SQL?

11

¿Por qué no podemos escribir sentencias ddl directamente en el bloque PL / SQL, por ejemplo cuando escribo

CREATE OR REPLACE PROCEDURE test IS
BEGIN
    truncate table table_name; // error
END test;
/

Pero,

CREATE OR REPLACE PROCEDURE test IS
BEGIN
    execute immediate 'truncate table table_name'; // works fine
END test;
/

¿Por qué el segundo se ejecutó con éxito?

Ravi
fuente

Respuestas:

7

Como dice en la documentación :

Solo el SQL dinámico puede ejecutar los siguientes tipos de declaraciones dentro de las unidades de programa PL / SQL:

  • Sentencias del lenguaje de definición de datos (DDL) como CREATE, DROP, GRANT y REVOKE

Una TRUNCATEoperación es DDL.

Cuando lo use EXECUTE IMMEDIATE, recuerde que cualquier DDLoperación que ejecute implícitamente será COMMITla transacción actual.

Philᵀᴹ
fuente
1

DDL dentro del código PL / SQL es más una excepción que una necesidad real. Parse puede verse como verificación de estructura, que se pierde si su estructura cambia en la ejecución. Los procedimientos están destinados a analizarse nuevamente otros objetos (tablas u otro código pl / sql, vistas, etc.). Cada vez que el objeto cambia, se debe volver a compilar. Por lo tanto, hacer un código analizado de algo que no sea la estructura de cambio no puede verificarse y, como tal, compilarse. Considerar caso

DROP TABLE T1;

Durante el tiempo de análisis, la tabla se encontraría y el procedimiento se compilaría con éxito, pero en la primera ejecución, la tabla se descarta y su código ya no es válido (la próxima vez que DROP TABLE resulte en un error). Del mismo modo, cualquier cambio en la tabla DDL crearía la necesidad de volver a compilar, por lo que perdería la ventaja del análisis de código.

igr
fuente