Oracleシェルで次を実行すると正常に動作します
truncate table table_name
しかし、私がそれをストアドプロシージャに入れようとすると
CREATE OR REPLACE PROCEDURE test IS
BEGIN
truncate table table_name;
END test;
/
失敗する
ERROR line 3, col 14, ending_line 3, ending_col 18, Found 'table', Expecting: @ ROW or ( or . or ; :=
どうして?
Oracle PL/SQLのすべてのDDLステートメントは、ステートメントの直前にExecuteを使用する必要があります。したがって、次を使用する必要があります。
execute immediate 'truncate table schema.tablename';
すぐに実行するだけでなく、使用することもできます
DBMS_UTILITY.EXEC_DDL_STATEMENT('TRUNCATE TABLE tablename;');
ストアドプロシージャがDDLを実行しており、DDLの一部のインスタンスがストアドプロシージャを無効にする可能性があるため、ステートメントは失敗します。 execute immediateまたはexec_ddlアプローチを使用することにより、DDLは未解析のコードを通じて実装されます。
これを行うとき、DDLが実行の前後に暗黙的なコミットを発行するという事実に注意する必要があります。
以下のコードを試してください
execute immediate 'truncate table tablename' ;
PL/SQLは遅延バインディングを直接サポートせず、DMLに適したコンパイル時バインディングのみをサポートするため、PL/SQLブロックからDMLに対して行うようにDDL文を直接実行することはできないことを知っておく必要があります。したがって、このタイプの問題を克服するために、OracleはDDLステートメントの実行に使用できる動的SQLアプローチを提供しました。動的SQLアプローチは、実行時のsql文字列の解析とバインドに関するものです。また、DDLステートメントはデフォルトで自動コミットであるため、DDLを実行する前にDML(TCLを使用して明示的にコミットする必要がある)がある場合は、動的SQLアプローチを使用するDDLステートメントに注意する必要があります。ストアドプロシージャ/関数。
次の動的SQLアプローチのいずれかを使用して、pl/sqlブロックからDDL文を実行できます。
1)即時実行
2)DBMS_SQLパッケージ
3)DBMS_UTILITY.EXEC_DDL_STATEMENT(parse_string IN VARCHAR2);
これが説明であなたの質問に答えることを願っています。