Microsoft SQL Server
      や、Sybaseでは、こんな風にストアドプロシージャでSELECT文を実行し、その結果セットをストアドプロシージャから返すことができます。
  create procedure sp_foo
   @key nvarchar(10)
  as
    SELECT empno, ename FROM emp
    WHERE empno >= @key
  end
OracleのPL/SQLプロシージャは、結果セットを返すことはありませんが、上記に近い機能は、以下のようにカーソルを返すプロシージャを定義することで、実現できます。
  create or replace package TestPkg is
    cursor empcursor is select empno, ename from emp;
    type t_empcursor is ref cursor return empcursor%rowtype;
    procedure SelectRecords(p_key in number, p_empcursor in out t_empcursor);
  end TestPkg;
  create or replace package body TestPkg is
    procedure SelectRecords(p_key in number, p_empcursor in out t_empcursor) is
    begin
       open p_empcursor for select empno, ename from emp where key >= p_key;
    end;
  end TestPkg;
カーソル変数の出力をDelphiアプリケーションで処理する方法
TOracleQueryによる方法
すでにTOracleQueryのセクションで説明した通り、ストアドプロシージャから返されたカーソルをもう一つのTOracleQueryに割当てて、そのQueryをOpenすることでカーソルからデータをフェッチします。
  //OpenQuery.SQL = 
  //  BEGIN
  //    TestPkg.SelectRecords(:Key, :EmpCursor);
  //  END;
  //OpenQuery.Variables: の変数宣言
  //  KEY = NUMBER型の変数
  //  EMPCURSOR = CURSOR型の変数
  //として…
  //
  procedure TForm1.Button4Click(Sender: TObject);
  begin
    with OpenQuery do begin
      SetVariable('Key', 1238);
      SetComplexVariable('EmpCursor', EmpFetchQuery);
      Execute;
    end;
    with EmpFetchQuery do begin
      Execute;
      while not Eof do begin
        Memo1.Lines.Add(Field('ENAME'));
        Next;
      end;
    end;
  end;
TOracleDataSetによる方法
TOracleDataSetは、SQLプロパティにセットされたSQL文中で、カーソル型の変数が一つ定義されている場合に、そのカーソルからレコードをフェッチしたものを、自身のデータセットとして扱うようになっています。したがって、SQLで変数にカーソルを取り出すように設定するだけで、結果セットをTDataSetとしてアクセスできるようになります
  //OraDataSet.SQL = 
  //  BEGIN
  //    TestPkg.SelectRecords(:Key, :EmpCursor);
  //  END;
  //    Key=number型の変数
  //    EmpCursor=カーソル型の変数
  //として…
  //
  procedure TForm1.Button4Click(Sender: TObject);
  begin
    with OraDataSet do begin
      SetVariable('Key', 1238);
      Open;
    end;
    with OraDataSet do begin
      First;
      while not Eof do begin
        Memo1.Lines.Add(Field('ENAME'));
        Next;
      end;
    end;
  end;
			