2012年6月17日日曜日

(PL/SQL)デバックモードでコンパイルした時のPLSQL_OPTIMIZE_LEVEL

自分だけ知らんなかったと思っていたら、他にも知らない者がいたので
まとめとく。


<<前提>>
下記のようなPL/SQLのプロシージャをOracle 11gで普通にコンパイルして
実行すると正常終了するが10gで実行するとEXCEPTIONに飛んで行き
 ”Error code -1843: ORA-01843: not a valid month
というメッセージが表示される。


create or replace procedure ttt is
  v_code  NUMBER;
  v_errm  VARCHAR2(64);
BEGIN
 IF TO_DATE('20112233','YYYYMMDD')>SYSDATE THEN    ' <<== ここの式に問題
  NULL;
 END IF;
EXCEPTION
 WHEN OTHERS THEN
   v_code := SQLCODE;
   v_errm := SUBSTR(SQLERRM, 1, 64);
   DBMS_OUTPUT.PUT_LINE('Error code ' || v_code || ': ' || v_errm);
END;


これは11gでは、ディフォルトの設定でPLSQL_OPTIMIZE_LEVELが2でコンパイルされ
IF文の中がNULLだけだとIF文自体を省略してコンパイルされるのでEXCEPTIONが発生する
式が実行されないのに対して10gはPLSQL_OPTIMIZE_LEVELが1でコンパイルされる為
IF文内のTO_DATE('20112233','YYYYMMDD')が実行されEXCEPTIONが発生する。




<<11gでデバックモードでコンパイルした時>>
で、SQL*Developer等でデバックする為、「デバック用にコンパイル」とかでコンパイルして
実行すると11gでもEXCEPTIONが発生するようになる。
この部分が全く知らなかった部分で11g上でデバックモードでコンパイルした場合、
PLSQL_OPTIMIZE_LEVELの設定値にかかわらず1と同等の状態でコンパイルされるという話。


実働環境にSQL*Developer等入れておくと時々デバックモードでコンパイルしたままに
なっている場合があるので、一応ご注意を。(しかし、最適化の資料少ないねぇ。はっきり
わかるのはこれ位で、あとは調べるのが面倒なINLINEがらみ。)

0 件のコメント:

コメントを投稿