web-dev-qa-db-ja.com

PL / SQLでRECORDのコレクションを手動で初期化する方法は?

みんな。これは、完全に機能しているPL/SQLの単純なサンプル2次元配列です。

declare
  type a is table of number;
  type b is table of a;

  arr b := b(a(1, 2), a(3, 4));
begin
  for i in arr.first .. arr.last loop
    for j in arr(i).first .. arr(i).last loop
      dbms_output.put_line(arr(i) (j));
    end loop;
  end loop;
end;

私がする必要があるのは、RECORDSのテーブルに似たものを作成することです。このような:

 type a is record(a1 number, a2 number);
 type b is table of a;

問題は、この種の配列を手動で初期化できるか、それともbulk collectsなどで埋められることになっているのかということです。上記と同じ構文は機能していないようで、マニュアルで初期化サンプルを見つけることができませんでした。

17
Kirill Leontev

RECORDには「コンストラクタ」構文がないため、次のように入力する必要があります。

declare
 type a is record(a1 number, a2 number);
 type b is table of a;
 arr b := b();
begin
 arr.extend(2);
 arr(1).a1 := 1;
 arr(1).a2 := 2;
 arr(2).a1 := 3;
 arr(2).a2 := 4;
end;
19
Tony Andrews

これはオブジェクトがなくても機能しますが、タイプ 'a'の値のコンストラクター関数を宣言する必要があります。

declare  
  type a is record(a1 number, a2 number);
  type b is table of a;

  arr b;

  --Constructor for type a
  function a_(a1 number, a2 number) return a is
    r_a a;
  begin
    r_a.a1 := a1;
    r_a.a2 := a2;

    return(r_a);
  end;

begin
  arr := b(a_(1, 2), a_(3, 4), a_(5, 6), a_(7, 8));

  for i in arr.first .. arr.last loop
    dbms_output.put_line(arr(i).a1||', '||arr(i).a2);
  end loop;
end;
14
Shallow

リリース18c以降 修飾式 は、複雑なデータ型の値を定義するための代替方法を提供します。見積もり:

Oracle Databaseリリース18c以降、コンストラクタが抽象データ型値を提供するように、任意のPL/SQL値を式(たとえば、レコードまたは連想配列)で提供できます。 PL/SQLでは、SQLの「型コンストラクタ」ではなく「修飾式」と「集計」という用語を使用しますが、機能は同じです。

これが実際の例です:

declare 
    type a is record (a1 number, a2 number);
    type b is table of a index by varchar2 (16);
    arr b := b ('key1' => a (1, 2), 'key2' => a (3, 4)); 
begin 
    declare key varchar2 (16) := arr.first; begin 
    <<foreach>> loop
        dbms_output.put_line (arr(key).a1||','||arr (key).a2);
        key := arr.next (key);
        exit foreach when key is null;
    end loop; end;
end;
/
PL/SQL procedure successfully completed.

1,2
3,4
4
0xdb