Oracleはプロシージャ・ファンクション・変数・定数・カーソル・例外などを、パッケージにまとめて扱うことができます。パッケージの中で定義されたパッケージ・プロシージャおよびパッケージ・ファンクションの呼び出しは、DOAを使えば、何の苦もなく行えます。
パッケージ・プロシージャの呼び出し(復習)
パッケージ・プロシージャを呼び出すには、PL/SQL無名ブロックから 「
[schema.]package.function_name[(param1, ...
paramN)]」という構文を使います(たとえば scott.testpkg.testproc(1,2); )。
TOracleQueryコンポーネントのSQLプロパティに、以下のようにプロシージャ呼び出しを行うPL/SQL無名ブロックを記述してExecuteメソッドを実行すればこのプロシージャを呼び出せます。
BEGIN MyPackage.TestProc1(10); END;
TOraclePackageによるプロシージャ・ファンクションの呼び出し
パッケージプロシージャの呼び出しは、上記に示したように、TOracleQueryを使っても可能ですが、TOraclePackageクラスを使うことで、もっと簡単に関数呼び出しが可能になります。ストアドプロシージャの呼び出しや,パッケージ変数へのアクセスは、ほとんどの場合
TOraclePackageを使うのが最も簡便な方法です。
たとえば、標準関数のSYSDATE関数をコールする方法を、TOraclePackageを使ったケースと、TOracleQueryを使うケースとを、以下に対比して示します。TOraclePackageの方が簡単ですよね?
例1) TOracleSQLを使った場合 //OracleQuery1.SQL = // BEGIN // :Result := SYSDATE; // END; // // Date型のOutput VariableとしてResultを定義 with OracleQuery1 do begin Execute; Showmessage('現在時刻は' + FormatDateTime('yyyy/mm/dd hh:nn:ss', GetVariable('Result'))); end;
例2) TOraclePackageを使った場合 // StandardPackage: TOraclePackage; // StandardPackage.PackageName = 'STANDARD' // procedure TForm1.Button5Click(Sender: TObject); begin Showmessage('現在時刻は' + FormatDateTime( 'yyyy/mm/dd hh:nn:ss', OraclePackage1.CallDateFunction('SYSDATE', []))); end;
TOraclePackageは、ユーザ定義のパッケージ関数を呼ぶためにも使えますし、上記の例のように標準関数(すなわちSTANDARDパッケージの関数)を呼ぶための簡易なインタフェースとしても、使いでがあるといえるでしょう。さらには、TOraclePackageのPackageNameプロパティを空にセットすることで、パッケージの外で独立して定義されたストアドプロシージャも呼び出せます。
すなわち、*:ストアドプロシージャを呼び出すときは常にTOraclePackageを使う
というやり方を、プロジェクトスタンダードとして採用することが考えられます。ある程度の規模のプロジェクトになると、PL/SQLプロシージャやパッケージを書く人と、それを使ってアプリケーションを作る人との分業を進める必要がありますが、プロシージャを専ら使う**立場のプログラマは、SQLを一切知らなくてもTOraclePackageを使ってプロシージャの利用に徹することが可能になるのです。
以下に示すとおり、種々の関数が用意されていて、引数を持つパッケージ関数/パッケージプロシージャの呼び出しが簡単に行えます。DOAは
パッケージ・ウィザードによってOracleのストアド・パッケージのそれぞれから、パッケージプロシージャをメソッドに対応づけたDelphiのクラスに変換することができ、さらにアプリケーションプログラマの負担を軽減できます(これについては別セクションにて説明します)。
TOracleQuery => TOraclePackage => Package Wizard
の順に、より洗練された、大規模プロジェクト向きのプログラミングが可能になっていると考えてよいでしょう。
-
TOraclePackage (ファンクション呼び出し関連)
- property
PackageName:
パッケージ名を文字列で指定します。STANDARDをセットすると標準関数がコールでき、何もセットしない(ヌル文字列)で使うと、パッケージの外で定義されたプロシージャをコールできます - function
CallIntegerFunction(ProcedureName; Parameters): Variant;
整数を返すファンクションを呼び出し、戻り値(整数)を返します。Parametersには、0個以上の引数を渡せます。たとえば、CallIntegerFunction(
TestFunc, [0, 1]); のように。 - function
CallFloatFunction(ProcedureName: Prameters):
Variant;戻り値(実数)を返すファンクションを実行 - function
CallBooleanFunction(ProcedureName; Parameters):
Variant;戻り値(真偽)を返すファンクションを実行 - function
CallDateFunction(ProcedureName; Parameters): Variant;
戻り値(日付時刻)を返すファンクションを実行 - function
CallStringFunction(ProcedureName; Parameters): Variant;
戻り値(文字列)を返すファンクションを実行
以下に、標準のパッケージSYS.DBMS_PIPEを用いてメッセージを受信する例を示します。
- property
with DbmsPipe do try Status := CallIntegerFunction('receive_message', ['demo_pipe', 60]); case Status of 0: AddMessageToMemo; 1: ShowMessage('Timeout'); 2: ShowMessage('Record in pipe too big for buffer'); 3: ShowMessage('Interrupted'); end; except on E:EOracleError do ShowMessage(E.Message); end;
-
TOraclePackage (プロシージャ呼び出し関連)
- procedure
CallProcedure(ProcedureName: string; Parameters: array of variant):
パッケージプロシージャを呼び出します。Parametersには、0個以上の引数を渡せます。たとえば、CallProcedure(
TestProc, [0, 1]); のように。 - property
ParameterMode:
パラメータを渡す際に、名前付きで渡すか、順番で渡すかを設定します- pmNamed: 名前表記の場合、CallProcedure(
TestProc, [
A, 0,
B, 1]); によって、 TestProc( A ==> 0, B==> 1);
という呼び出し表記がとられます - pmPositional: 位置表記の場合、CallProcedure(
TestProc, [0, 1]); とすれば TestProc( 0, 1);
として呼び出されます。こちらがデフォルトです
- pmNamed: 名前表記の場合、CallProcedure(
- property
GetParameter(ParameterId: integer):Variant;
プロシージャの出力変数の値にアクセスできます。パラメータのインデックスは、一番最初のパラメータがParameterId=0に相当します - property
GetParameter(ParameterId: string): Variant;
プロシージャの出力変数の値に、パラメータ名でアクセスします
- procedure
以下に、標準のパッケージSYS.DBMS_PIPEを用いて受信メッセージを取り出す例を示します
with DbmsPipe do try CallProcedure('unpack_message', [parString]); Memo.Items.Add(GetParameter(0)); except on E:EOracleError do ShowMessage(E.Message); end;
-
TOraclePackage (パッケージ変数・定数関連)
- procedure
SetVariable(VariableName: string; Value: Variant);
パッケージ変数の値をセットします - function
GetIntegerVariable(VariableName: string):Variant;
変数または定数(整数)の値を取得します - function
GetFloatVariable(VariableName: string):Variant;
変数または定数(実数)の値を取得します - function
GetBooleanVariable(VariableName: string):Variant;
変数または定数(真偽)の値を取得します - function
GetDateVariable(VariableName: string):Variant;
変数または定数(日付時刻)の値を取得します - function
GetStringVariable(VariableName: string):Variant;
変数または定数(文字列)の値を取得します
- procedure
パッケージ変数にアクセスする例を示します
MaxWait := DbmsPipe.GetIntegerVariable('maxwait'); MyPackage.SetVariable('factor', 12.55);