TOracleQueryのSQLプロパティにSELECT文を用いた場合、TOracleQueryはSELECT文の生成する暗黙のカーソルにアクセスしています。

実は、PL/SQLブロックの中でDECLARE CURSOR
を使って明示的に開いたカーソルについても、TOracleQueryコンポーネントによってアクセスすることが可能です。これには以下の手順が必要です。

  1. 第一のTOracleQueryのSQLプロパティのPL/SQLブロックにおいて、カーソルを明示的に宣言してOPENするように記述します
  2. 第一のTOracleQueryにCursor型パラメータ(input/output variable)を宣言します
  3. 別のTOracleQueryを用意し、SetComplexVariableメソッドを使ってカーソル変数を関連付けます
  4. その上で、第一のクエリを実行します

このような手法用いると、第一のクエリのPL/SQLブロック中で複数のカーソルを一気にオープンするようなことも可能です。以下に実例を示します。

  //OpenQuery.SQL = 
  //  BEGIN
  //    OPEN :EMPCURSOR FOR  SELECT * FROM EMP;
  //    OPEN :DEPTCURSOR FOR SELECT * FROM DEPT;
  //  END;
  //OpenQuery.Variables: の変数宣言
  //  EMPCURSOR = CURSOR型の変数
  //  DEPTCURSOR = CURSOR型の変数
  //として…
  //
  procedure TForm1.Button4Click(Sender: TObject);
  begin
    with OpenQuery do begin
      SetComplexVariable('EmpCursor', EmpFetchQuery);
      SetComplexVariable('DeptCursor',DeptFetchQuery);
      Execute;
    end;

    Memo1.Lines.Add('DEPT----');
    with EmpFetchQuery do begin
      Execute;
      while not Eof do begin
        Memo1.Lines.Add(Field('ENAME'));
        Next;
      end;
    end;

    Memo1.Lines.Add('DEPT----');
    with DeptFetchQuery do begin
      Execute;
      while not Eof do begin
        Memo1.Lines.Add(Field('DNAME'));
        Next;
      end;
    end;
  end;

このように、TOracleQueryクラスの本質は、カーソルにアクセスするためのクラスであることがわかると思います。ストアドプロシージャ内で開いたカーソルをoutput引数で返す場合にも、このカーソルへのアクセスがTOracleQueryによって可能です。

  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_empcursor in out t_empcursor);
  end TestPkg;

  create or replace package body TestPkg is
    procedure SelectRecords(p_empcursor in out t_empcursor) is
    begin
       open p_empcursor for select empno, ename from emp;
    end;
  end TestPkg;

たとえば、上記のプロシージャを実行して結果にアクセスするには、以下のようにします。

  //OpenQuery.SQL = 
  //  BEGIN
  //    TestPkg.SelectRecords(:EMPCURSOR);
  //  END;
  //OpenQuery.Variables: の変数宣言
  //  EMPCURSOR = CURSOR型の変数
  //として…
  //
  procedure TForm1.Button4Click(Sender: TObject);
  begin
    with OpenQuery do begin
      SetComplexVariable('EmpCursor', EmpFetchQuery);
      Execute;
    end;
    with FetchQuery do begin
      Execute;
      while not Eof do begin
        Memo1.Lines.Add(Field('EMPNO') + ', ' + Field('ENAME'));
        Next;
      end;
    end;
  end;