web-dev-qa-db-ja.com

Oracleのdeclare / begin / endブロックから行を返す方法は?

宣言/開始/終了ブロック内のselectステートメントから行を返したい。これはT-SQLで実行できますが、PL/SQLで実行する方法を知りたいです。

コードは次のようになります。

declare
     blah number := 42;
begin
     select *
     from x
     where x.value = blah;
end;
15
Thomas Bratt

示したような匿名のPL/SQLブロックは、何も「返す」ことができません。ただし、バインド変数を使用して呼び出し元と対話できます。

したがって、この場合に使用する方法は、カーソル参照を宣言し、それをPL/SQLブロックで開いて目的のクエリを実行し、呼び出し元のアプリケーションにそこから行をフェッチさせることです。 SQLPlusでは、これは次のようになります。

variable rc refcursor

declare
     blah number := 42;
begin
  open :rc for
     select *
     from x
     where x.value = blah;
end;
/

print x

PL/SQLをストアド関数として再キャストすると、値が返される可能性があります。この場合、コレクションタイプを作成し、すべての行をそのタイプの変数にフェッチして、それを返すことができます。

CREATE TYPE number_table AS TABLE OF NUMBER;

CREATE FUNCTION get_blah_from_x (blah  INTEGER)
  RETURN number_table
  IS
    values  number_table;
  BEGIN
    SELECT id
      BULK COLLECT INTO values
      FROM x
      WHERE x.value = blah;
    RETURN values;
  END;
/
11
Dave Costa

これは、データアクセスライブラリに大きく依存します。

SQL互換の型をパラメータとして返すことができます。これには、複雑なSQLタイプとコレクションタイプが含まれます。しかし、ほとんどのライブラリは、Oracleのオブジェクトタイプを処理することができません。

いずれにせよ、私の例では次のオブジェクトタイプを使用します。

create type SomeType as object(Field1 VarChar(50));

create type SomeTypeList as table of SomeType;

アクセスライブラリがオブジェクトタイプを処理できる場合は、PL/SQLオブジェクトのリストを返すだけです。

begin
  :list := SomeTypeList(SomeType('a'),SomeType('b'),SomeType('c'));
end;

そうでない場合は、このリストを強制的に選択して、その結果をカーソルとして返すことで、ハックすることができます。

declare
  list SomeTypeList;
begin
  list := SomeTypeList(SomeType('a'),SomeType('b'),SomeType('c'));
  open :yourCursor for
    SELECT A
    FROM   table(list);
end;
0
Robert Giesecke