Lorsque je lance ce qui suit dans un shell Oracle, cela fonctionne bien
truncate table table_name
Mais quand j'essaye de le mettre dans une procédure stockée
CREATE OR REPLACE PROCEDURE test IS
BEGIN
truncate table table_name;
END test;
/
il échoue avec
ERROR line 3, col 14, ending_line 3, ending_col 18, Found 'table', Expecting: @ ROW or ( or . or ; :=
Pourquoi?
Toutes les instructions DDL dans Oracle PL/SQL doivent utiliser Exécuter immédiatement avant l'instruction. Par conséquent, vous devez utiliser:
execute immediate 'truncate table schema.tablename';
En plus d'exécuter immédiatement, vous pouvez également utiliser
DBMS_UTILITY.EXEC_DDL_STATEMENT('TRUNCATE TABLE tablename;');
L'instruction échoue car le proc stocké exécute DDL et certaines instances de DDL peuvent invalider le proc stocké. En utilisant les approches execute immediate ou exec_ddl, la DDL est implémentée via un code non analysé.
Ce faisant, vous devez vérifier que DDL émet un commit implicite avant et après l'exécution.
essayez le code ci-dessous
execute immediate 'truncate table tablename' ;
Vous devez savoir qu'il n'est pas possible d'exécuter directement une instruction DDL comme vous le faites pour DML à partir d'un bloc PL/SQL car PL/SQL ne prend pas directement en charge la liaison tardive, il ne prend en charge que la liaison au moment de la compilation, ce qui est bien pour DML. Par conséquent, pour surmonter ce type de problème, Oracle a fourni une approche SQL dynamique qui peut être utilisée pour exécuter les instructions DDL. L'approche SQL dynamique concerne l'analyse et la liaison de la chaîne SQL au moment de l'exécution. Vous devez également vous rappeler que les instructions DDL sont par défaut auto commit, vous devez donc faire attention à toute instruction DDL utilisant l'approche SQL dynamique dans le cas où vous avez du DML (qui doit être validé explicitement à l'aide de TCL) avant d'exécuter le DDL dans le proc/fonction stockée.
Vous pouvez utiliser l'une des approches SQL dynamiques suivantes pour exécuter une instruction DDL à partir d'un bloc pl/sql.
1) Exécuter immédiatement
2) Package DBMS_SQL
3) DBMS_UTILITY.EXEC_DDL_STATEMENT (parse_string IN VARCHAR2);
J'espère que cela répond à votre question avec des explications.