CALL 文 と EXECUTE コマンドの違い
CALL は Oracle 9i からサポートされた 標準SQL のコマンドであり、EXECUTE は旧来からある SQL*Plus コマンド である。(※ PL/SQL のコマンドでもない)
双方ともファンクションやプロシージャの実行に使用するが、その仕様は異なり新しく用意された CALL が良いというものでもないといえる。
Oracle 10g までは CALL の引数は位置表記法のみに限定されていたが Oracle 11g からは 位置表記法および両方を併用した混合表記も可能になっている。
同時に SQL の関数の呼び出しも 位置表記法と混合表記がサポートされた。
EXECUTE の実行例
EXECUTE コマンドは テキストを PL/SQL ブロックに変換してから実行する。
EXECUTE plsql_text; は BEGIN plsql_text; END; に変換してから実行されているということである。
SQL> variable num number;
SQL> EXECUTE :num := function_hoge('あいう', TRUE);
↓ 変換
BEGIN :num := function_hoge('あいう', TRUE); END;
↓ 実行
PL/SQLプロシージャが正常に完了しました。
SQL> print :num
...
CALL の実行例
CALL による呼び出しで、 SQL としてまだサポートされていない BOOLEAN 型 (TRUE/FALSE) を PL/SQL のファンクションに使用すると・・・
SQL> variable num number;
SQL> CALL function_hoge('あいう', TRUE) INTO :num ;
*
行1でエラーが発生しました。:
ORA-06553: PLS-306: 'FUNCTION_HOGE'の呼出しで、引数の数または型が正しくありません。
のようにエラーが発生する。
(予想であるが)SQL のパーサー経由(※) と PL/SQL パーサー経由で実行される差のようなものがあると思われる。
(※) CALL 経由で PL/SQL に組み込まれていない関数(例えば ORA_HASH)を呼び出しても利用できないことから SQL として実行はされていない。
例外発生時のハンドリング(出力表示)の違い
一部の例外について扱いが異なっている。
- 異なる場合
プロシージャ(ORA-01403:NO_DATA_FOUND を明示的に発生させている)
CREATE OR REPLACE PROCEDURE TEST_ORA_01403
IS BEGIN
RAISE NO_DATA_FOUND;
END;
/
NO_DATA_FOUND ⇒ PL/SQL の事前定義例外
呼び出し
SQL> execute TEST_ORA_01403;
BEGIN TEST_ORA_01403; END;
*
行1でエラーが発生しました。:
ORA-01403: データが見つかりません。 ORA-06512:
"RIVUS.TEST_ORA_01403", 行4
ORA-06512: 行1
SQL> call TEST_ORA_01403();
コールが完了しました。
- 同じ場合
プロシージャ(ORA-01422:TOO_MANY_ROWS を明示的に発生させている)
CREATE OR REPLACE PROCEDURE TEST_ORA_01422
IS BEGIN
RAISE TOO_MANY_ROWS;
END;
/
呼び出し
SQL> execute TEST_ORA_01422;
BEGIN TEST_ORA_01422; END;
*
行1でエラーが発生しました。:
ORA-01422: 完全フェッチがリクエストよりも多くの行を戻しました ORA-06512:
"RIVUS.TEST_ORA_01422", 行4
ORA-06512: 行1
SQL> call TEST_ORA_01422();
call TEST_ORA_01422()
*
行1でエラーが発生しました。:
ORA-01422: 完全フェッチがリクエストよりも多くの行を戻しました ORA-06512:
"RIVUS.TEST_ORA_01422", 行4