TOraclePackageによるプロシージャの実行

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を用いてメッセージを受信する例を示します。
  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); として呼び出されます。こちらがデフォルトです
    • property GetParameter(ParameterId: integer):Variant; プロシージャの出力変数の値にアクセスできます。パラメータのインデックスは、一番最初のパラメータがParameterId=0に相当します
    • property GetParameter(ParameterId: string): Variant; プロシージャの出力変数の値に、パラメータ名でアクセスします

以下に、標準のパッケージ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; 変数または定数(文字列)の値を取得します

パッケージ変数にアクセスする例を示します

  MaxWait := DbmsPipe.GetIntegerVariable('maxwait'); 

  MyPackage.SetVariable('factor', 12.55); 

△[] ▼[続き]