DirectoOracleAccessを使ってストアドプロシージャを呼び出します。
プロシージャ呼出の基本3パターン
以下の3つについて順に説明します。
- 結果を返さないプロシージャの呼び出し(INPUT変数の渡し方)
- プロシージャ呼出し後、OUTPUT変数からの結果の取得
- カーソル変数を利用したプロシージャからのレコードセットの取得
1)結果を返さない手続き型のプロシージャ
右のようなプロシージャを考えます(引数を10回くりかえしてDBMS_Output出力します) |
create or replace procedure TestProc1(N IN NUMBER) is i number; begin for i in 1 .. 10 loop dbms_output.put_line(N); end loop; end TestProc1; |
これを右のようなアプリケーションで呼んでみましょう 画面上のオブジェクトは左上から順に Session: TOracleSession Query1: TOracleQuery Button1: TButton Memo: TMemo で、 SessionのユーザID/Passwd/Database が適切に設定されてDBに接続でき Query1.SessionがSessionになっているとします |
|
1-1(引数なしのとき) Query1.SQLをこのように設定して |
begin TestProc1( 3 ); end; |
Button1.Clickイベントをこう記述して
|
procedure TForm1.Button1Click(Sender: TObject); var Status: integer; Line: string; begin Session.DBMS_Output.Enable(100000); Query1.Execute; |
テスト実行すると結果は
|
メモに数字の3が10回繰り返して表示されるはずです。 |
TestProc1の引数を変数から与えるには Query1.SQLをこのように設定して |
begin TestProc1( :N ); end; |
Query1のVariablesプロパティのプロパティエディタを開いて、「Scan SQL」を実行すると、上記SQL文中からパラメータが抽出されてVariablesとしてリストに現れます。 一番目の「:N」をクリックして、 整数型として定義します。 |
|
フォーム上にエディットボックスEdit1を置いて、 今度はButton1.Clickをこのように変えて |
procedure TForm1.Button1Click(Sender: TObject); var Status: integer; Line: string; begin Session.DBMS_Output.Enable(100000); with Query1 do begin Close; SetVariable(★ |
実行し、Edit1に数字をいれてボタンをクリックすると、結果は… | Edit1に入力した数字が10回繰り返されて出力されます |
2)計算結果をパラメータで返すストアドプロシージャ
例としてインプットを二乗して返す手続きを用意した |
create or replace procedure TestProc2( N IN NUMBER, R OUT NUMBER) is begin R := N * N; end TestProc2; |
Query1.SQLを右のようにセット
|
declare R number; begin TestProc2(6, R); select R into :R From Dual; end; |
Query1.Variablesプロパティのプロパティエディタを開き、出力パラメータ:Rを設定する | |
Button1Clickは右のようにして |
procedure TForm1.Button1Click(Sender: TObject); begin Query1.Execute; Memo.Clear; Memo.Lines.Add(★
|
実行すれば
|
メモに「 R = 36 」と出力される |
補足
|
上記の例においては、Query1.SQLを以下のようにした方がもっと直接的です。 begin TestProc2( 6, :R); end; または begin TestProc2( N => 6, R => :R); end; なお、プロシージャをパッケージ内で宣言した場合は、TOraclePackageコンポーネントが簡便です。 |
3)SELECT文の結果を返すストアドプロシージャ
右のようなパッケージを用意します
Sybase/SQL-Server風にいえば create procedure SelectRecords as begin select empno, ename from emp; end; のような感じにしたい場合の話です。 |
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; |
では、このプロシージャSelectRecordsの結果セットをグリッド表示してみましょう。 先程までのテストプログラムのTQueryの代わりにTOracleDataSetを使い、MemoのかわりにDBGridを配置して右のような画面を作ります。 |
|
OracleDataSet1.SQLは次のようにセットします |
begin TestPkg.SelectRecords( :CURSOR ); end; |
※重要!トリッキーですが…※ OracleDataSet1.Variablesのプロパティエディタで Cursor型のVariableとしてCURSORを定義します こうすると、この変数が、当データセットのためのカーソルになるのです。 |
|
Button1Clickイベントで、OracleDataset1を開くように設定しておく
|
procedure TForm1.Button1Click(Sender: TObject); begin OracleDataSet1.Open; end; |
これを実行すると、プロシージャが実行され、出力用のカーソルの指すデータセットがグリッド表示されます。 そうです。Oracleのストアドプロシージャでselect文を実行させた、その結果をデータベース対応コンポーネントで参照・編集が可能です。 |
|
補足
|
カーソルの定義に、ROWIDを取得対象に含めることで、更新可能なデータセットになります。(DOAによるデータベース更新に関するトピックを参照のこと) |