web-dev-qa-db-ja.com

ストアドプロシージャ内のテーブルの切り捨て

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   ;   :=

どうして?

47
Klas Mellbourn

Oracle PL/SQLのすべてのDDLステートメントは、ステートメントの直前にExecuteを使用する必要があります。したがって、次を使用する必要があります。

execute immediate 'truncate table schema.tablename';
101
Dheer

すぐに実行するだけでなく、使用することもできます

DBMS_UTILITY.EXEC_DDL_STATEMENT('TRUNCATE TABLE tablename;');

ストアドプロシージャがDDLを実行しており、DDLの一部のインスタンスがストアドプロシージャを無効にする可能性があるため、ステートメントは失敗します。 execute immediateまたはexec_ddlアプローチを使用することにより、DDLは未解析のコードを通じて実装されます。

これを行うとき、DDLが実行の前後に暗黙的なコミットを発行するという事実に注意する必要があります。

17
stjohnroe

以下のコードを試してください

execute immediate 'truncate table tablename' ;
11
serioys sam

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);

これが説明であなたの質問に答えることを願っています。

10
Gourabp