TOracleQueryのSQLプロパティにSELECT文を用いた場合、TOracleQueryはSELECT文の生成する暗黙のカーソルにアクセスしています。
実は、PL/SQLブロックの中でDECLARE CURSOR
を使って明示的に開いたカーソルについても、TOracleQueryコンポーネントによってアクセスすることが可能です。これには以下の手順が必要です。
- 第一のTOracleQueryのSQLプロパティのPL/SQLブロックにおいて、カーソルを明示的に宣言してOPENするように記述します
- 第一のTOracleQueryにCursor型パラメータ(input/output variable)を宣言します
- 別のTOracleQueryを用意し、SetComplexVariableメソッドを使ってカーソル変数を関連付けます
- その上で、第一のクエリを実行します
このような手法用いると、第一のクエリの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;