web-dev-qa-db-fra.com

Pourquoi ne pouvons-nous pas écrire l'instruction ddl directement dans le bloc PL / SQL

Pourquoi ne pouvons-nous pas écrire des instructions ddl directement dans un bloc PL/SQL, par exemple lorsque j'écris

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

Mais,

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

Pourquoi le second s'est-il exécuté avec succès?

11
Ravi

Comme il est dit dans la documentation :

Seul le SQL dynamique peut exécuter les types d'instructions suivants dans les unités de programme PL/SQL:

  • Instructions DDL (Data Definition Language) telles que CREATE, DROP, GRANT et REVOKE

Une opération TRUNCATE est DDL.

Lors de l'utilisation de EXECUTE IMMEDIATE, rappelez-vous que toute opération DDL que vous exécutez implicitement COMMIT la transaction en cours.

7
Philᵀᴹ

DDL à l'intérieur du code PL/SQL est plus une exception qu'un besoin réel. L'analyse peut être considérée comme une vérification de structure, qui est perdue si votre structure change lors de l'exécution. Les procédures sont destinées à être analysées à nouveau avec d'autres objets (tables, ou autre code pl/sql, vues, etc.). Chaque fois que l'objet change, il doit être recompilé. Donc, faire du code analysé de quelque chose que changer la structure ne peut pas être vérifié et en tant que tel compilé. Considérez le cas

DROP TABLE T1;

Pendant le temps d'analyse, la table serait trouvée et la procédure correctement compilée mais à la 1ère exécution, la table est supprimée et votre code n'est plus valide (la prochaine fois DROP TABLE entraînerait une erreur). De même, toute modification de la table DDL créerait un besoin de recompilation, perdant ainsi l'avantage de l'analyse de code.

1
igr