3

それが正しい用語かどうかはわかりませんが、次のように作成されたオブジェクトに対して「メモリ内テーブル」を呼び出します。

create type InMemReg is object (field1 varchar2(10), field2 varchar2(20), field3 number);
create type InMemTab is table of InMemReg;

この場合、「メモリ内テーブル」は「InMemTab」です。私の質問は、以前に要素の数がわからない場合に、この種のオブジェクトをどのように設定できるかです。私はいくつかの場所でこのタイプの初期化を見てきました:

declare
  v_uno InMemReg := InMemReg('a','b',1999);
  v_dos InMemReg := InMemReg('A','Z',2000);
  t_tres  InMemTab := InMemTab();
begin
  t_tres := InMemTab(v_uno, v_dos);

この状況では、「t_tres」を初期化する前に明示的に 2 つのオブジェクトがありますが、n 個の要素を持つことができる動的なシナリオでは、それを設定する方法がわかりません。

別の OO 言語では、次のようになります。

t_tres.add(OtherObject)
4

2 に答える 2

10

この型InMemTabは、Oracle 用語ではネストされたテーブルです。

メソッドに相当するのは、addメソッドを呼び出してから、ネストされたテーブルの最後の位置にextend割り当てることです。OtherObject

SQL> ed
Wrote file afiedt.buf

  1  declare
  2    v_uno InMemReg := InMemReg('a','b',1999);
  3    v_dos InMemReg := InMemReg('A','Z',2000);
  4    t_tres  InMemTab := InMemTab();
  5  begin
  6    t_tres.extend;
  7    t_tres( t_tres.count ) := v_uno;
  8    t_tres.extend;
  9    t_tres( t_tres.count ) := v_dos;
 10    dbms_output.put_line( 't_tres has ' || t_tres.count || ' elements.' );
 11* end;
 12  /
t_tres has 2 elements.

PL/SQL procedure successfully completed.

addそれを手順に組み込むこともできます

SQL> ed
Wrote file afiedt.buf

  1  declare
  2    v_uno InMemReg := InMemReg('a','b',1999);
  3    v_dos InMemReg := InMemReg('A','Z',2000);
  4    t_tres  InMemTab := InMemTab();
  5    procedure add( p_nt    IN OUT InMemTab,
  6                   p_elem  IN     InMemReg )
  7    as
  8    begin
  9      p_nt.extend;
 10      p_nt( p_nt.count ) := p_elem;
 11    end;
 12  begin
 13    add( t_tres, v_uno );
 14    add( t_tres, v_dos );
 15    dbms_output.put_line( 't_tres has ' || t_tres.count || ' elements.' );
 16* end;
 17  /
t_tres has 2 elements.

PL/SQL procedure successfully completed.
于 2012-08-29T21:54:36.673 に答える
7

データ自体からコレクションを設定するのが一般的です。つまり、文字列と数値のセットを明示的に追加するのではなく、他のテーブルからデータを取得します。これはコレクションで一般的かつ自然なことであるため、オラクルは pl/sql の「BULK COLLECT INTO」句を使用して簡単にしました。例えば:

DECLARE
   TYPE EmployeeSet IS TABLE OF employees%ROWTYPE;
   underpaid EmployeeSet;
     -- Holds set of rows from EMPLOYEES table.
   CURSOR c1 IS SELECT first_name, last_name FROM employees;
   TYPE NameSet IS TABLE OF c1%ROWTYPE;
   some_names NameSet;
     -- Holds set of partial rows from EMPLOYEES table.
BEGIN
-- With one query,
-- bring all relevant data into collection of records.
   SELECT * BULK COLLECT INTO underpaid FROM employees
      WHERE salary < 5000 ORDER BY salary DESC;
-- Process data by examining collection or passing it to
-- eparate procedure, instead of writing loop to FETCH each row.
   DBMS_OUTPUT.PUT_LINE
     (underpaid.COUNT || ' people make less than 5000.');
   FOR i IN underpaid.FIRST .. underpaid.LAST
   LOOP
     DBMS_OUTPUT.PUT_LINE
       (underpaid(i).last_name || ' makes ' || underpaid(i).salary);
   END LOOP;
-- You can also bring in just some of the table columns.
-- Here you get the first and last names of 10 arbitrary employees.
   SELECT first_name, last_name
     BULK COLLECT INTO some_names
     FROM employees
     WHERE ROWNUM < 11;
   FOR i IN some_names.FIRST .. some_names.LAST
   LOOP
      DBMS_OUTPUT.PUT_LINE
        ('Employee = ' || some_names(i).first_name
         || ' ' || some_names(i).last_name);
   END LOOP;
END;
/

通常、拡張や要素の数について心配する必要はありません。通常、それを丸呑みしてから、コレクションの組み込み機能を好きなように使用できます (カウント、ループスルー、異なるコレクションの比較、操作の設定)など)

于 2012-08-31T01:12:08.493 に答える