PL/SQL 配列のINDEXが飛び飛びな時のFORALL

配列のINDEXが飛び飛びな状態で
FORALL文を実行すると、エラーになるんですね。

どうすればいいか?をやっていこうと思います。

まずはエラーになる例

まず初めに、こうやるとエラーになりますよ
という例から。。。

declare
  cursor cur_common is
    select
      ID
     ,NAME
    from COMMON_MST
    order by
      ID
  ;
  type type_common_tbl is table of cur_common%rowtype index by pls_integer;
  tbl_common  type_common_tbl;
  
begin
  open cur_common;
  fetch cur_common bulk collect into tbl_common;
  close cur_common;
  
  if (tbl_common.count > 0) then
    -- 配列のINDEX:3を削除してしまう
    tbl_common.delete(3);
    
    forall i in tbl_common.first..tbl_common.last
      insert into COMMON_MST_COPY
      (
        ID
       ,NAME
      )
      values
      (
        tbl_common(i).ID
       ,tbl_common(i).NAME
      )
    ;
    commit;
  end if;
end;

20行目で
INDEXが3のデータを削除しています。
INDEXが飛び飛びの状態を作りました。

この状態で、22行目〜のように
「配列を最初から最後まで」INSERTしようとしたら
エラーになります。

めっちゃ「3がないよ!」って言ってますね。

INDICESを使う

初めてみた…
「インドゥシーズ」って感じな発音らしい…
(英語は大の苦手です♪)

こう書きます。

declare
  cursor cur_common is
    select
      ID
     ,NAME
    from COMMON_MST
    order by
      ID
  ;
  type type_common_tbl is table of cur_common%rowtype index by pls_integer;
  tbl_common  type_common_tbl;
  
begin
  open cur_common;
  fetch cur_common bulk collect into tbl_common;
  close cur_common;
  
  if (tbl_common.count > 0) then
    -- 配列のINDEX:3を削除してしまう
    tbl_common.delete(3);
    
    forall i in indices of tbl_common
      insert into COMMON_MST_COPY
      (
        ID
       ,NAME
      )
      values
      (
        tbl_common(i).ID
       ,tbl_common(i).NAME
      )
    ;
    commit;
  end if;
end;

さっきと変わったのは22行目だけです。

forall <INDEX名> in indices of <配列名>

こうするだけ。

以上ですw

ちなみにこの「indices」ってやつ、
INDEXが飛び飛びじゃなくても使えます。

じゃあ…

forall <INDEX名> in <配列名>.first..<配列名>.last
forall <INDEX名> in 1..<配列名>.count

とか使わないで、全部こっちでいいじゃん!

forall <INDEX名> in indices of <配列名>

…というお話でしたw

本当に全部この書き方にするかは…

他の人がこの書き方を見たときに
絶対に「何これ!?」ってなるので、
どうしようか考え中ですw

PL/SQL

Posted by kiri