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);