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?
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.
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.