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;
