PL/SQLでループ中に例外が発生しても続行するロジック

PL/SQLで「ループ中に例外が発生した時は、その行だけ飛ばして次の行の処理を実行したい」という場合、ループ内に「BEGIN…END」をもう1つ記述することで実現できます。

例えば以下のサンプルは、売上伝票テーブルにある項目「顧客ID」を使用して、別テーブル「顧客情報テーブル」にそのIDで問い合わせて顧客コードを取得し、別テーブルにINSERTするというものです。

このとき、11行目のSELECT文で問い合わせ結果がない(顧客情報テーブルから不要な顧客が削除されていたりして、IDに紐づく顧客レコードが取得できない)場合、EXCEPTION節に処理が移りますが、「BEGIN…END」をはさんでいることで、EXCEPTION節の処理が実行後は、次のレコードを処理する、ということが可能になります。

いやー、はまりました。

DECLARE
 CURSOR cu is SELECT 顧客ID FROM 売上伝票TBL;
 TEMP VARCHAR2(32);

BEGIN

 FOR cu_rec IN cu loop
    
  BEGIN

   SELECT 顧客コード INTO TEMP 顧客TBL WHERE id = cu_rec.顧客ID;

--処理
   INSERT INTO 登録TBL(顧客コード) VALUES (TEMP);

--例外処理
   EXCEPTION
    WHEN NO_DATA_FOUND THEN
     INSERT INTO 登録TBL(顧客コード) VALUES ('HOGE');

  END;

 END LOOP;

COMMIT;
END;