SQL 解説書

CALL

データベースに保管されたプロシージャーを呼び出します。 たとえば、ストアード・プロシージャーは、データベースの位置で実行されて、 クライアント・アプリケーションにデータを戻します。

SQL CALL ステートメントを使用するプログラムは、 クライアントとサーバーの 2 つの部分で実行されるように設計されます。 データベースのサーバー・プロシージャーは、 クライアント・アプリケーションと同じトランザクション内で実行されます。 クライアント・アプリケーションとストアード・プロシージャーが同じ区分にある場合、 ストアード・プロシージャーはローカルに実行されます。

呼び出し

このステートメントは、アプリケーション・プログラムに組み込む方法のみ可能です。 これは、動的に準備できない実行可能ステートメントです。 ただし、プロシージャー名はホスト名によって指定することができます。 これは、USING DESCRIPTOR 文節の使用とを組み合わせることによって、 プロシージャー名とパラメーター・リストの両方を実行時に容易することができます。 これにより、動的準備が可能なステートメントと同じ効果が得られます。

許可

許可の規則は、プロシージャーが保管されているサーバーによって異なります。

DB2 ユニバーサル・データベース:
CALL ステートメントの許可 ID の特権には、 実行時に以下の特権のうち少なくとも 1 つが含まれていなければなりません。

DB2 ユニバーサル・データベース (OS/390 版):
CALL ステートメントの許可 ID の特権には、 バインド時に以下の特権のうち少なくとも 1 つが含まれていなければなりません。

DB2 (AS/400 版):
CALL ステートメントの許可 ID の特権には、 バインド時に以下の特権のうち少なくとも 1 つが含まれていなければなりません。

構文

>>-CALL----+-procedure-name-+----------------------------------->
           '-host-variable--'
 
>-----+---------------------------------------+----------------><
      +-(--+---------------------------+---)--+
      |    |  .-,--------------------. |      |
      |    |  V               (1)    | |      |
      |    '----host-variable--------+-'      |
      '-USING--DESCRIPTOR--descriptor-name----'
 

注:

  1. DB2 ユニバーサル・データベース (OS/390 版) サーバーおよび DB2 ユニバーサル・データベース (AS/400 版) サーバーにあるストアード・プロシージャーで、 DB2 ユニバーサル・データベース (OS/390 版) クライアントまたは DB2 ユニバーサル・データベース (AS/400 版) クライアントによって呼び出されるプロシージャーでは、 プロシージャー引き数として他のソース (たとえば定数値) がサポートされます。 ただし、ストアード・プロシージャーが DB2 ユニバーサル・データベースにある場合、 またはプロシージャーが DB2 ユニバーサル・データベース・クライアントから呼び出される場合は、 引き数はすべてホスト変数を介して与える必要があります。

説明

procedure-name または host-variable
呼び出すプロシージャーを指定します。 プロシージャー名は、直接指定するか (procedure-name)、 またはホスト変数 (host-variable) の中に指定できます。 指定するプロシージャーは、現行サーバーに存在していなければなりません (SQLSTATE 42724)。

procedure-name を指定する場合、 それは 254 バイト以下の通常識別子でなければなりません。 通常識別子だけを指定できるので、 ブランクや特殊文字を含めることができず、値は大文字に変換されます。 したがって、小文字名、ブランク、または特殊文字を使用する必要がある場合は、 名前を host-variable (ホスト変数) によって指定する必要があります。

host-variable が指定されている場合、 それは、長さ属性が 254 バイト以下の文字ストリング変数でなければならず、 標識変数を含めることはできません。 値は大文字に変換されないことに注意してください。procedure-name は左そろえでなければなりません。

プロシージャー名は、いくつかの形式のいずれかを使用して指定できます。 サポートされる形式は、プロシージャーが保管されているサーバーによって異なります。

DB2 ユニバーサル・データベース:

procedure-name
実行するプロシージャーの名前 (拡張子なし)。 呼び出されるプロシージャーは、以下のように決定されます。

  1. procedure-name は、ストアード・プロシージャー・ライブラリーの名前と、 そのライブラリー中の関数名の両方として使用されます。 たとえば、procedure-nameproclib の場合、 DB2 サーバーは、 proclib という名前のストアード・プロシージャー・ライブラリーをロードし、 そのライブラリー中の関数ルーチン proclib() を実行します。

    UNIX 系システムの場合、DB2 サーバーは、 デフォルト・ディレクトリーの sqllib/function から ストアード・プロシージャー・ライブラリーを検索します。 非分離ストアード・プロシージャーは、 sqllib/function/unfenced ディレクトリーにあります。

    OS/2 では、ストアード・プロシージャーの位置は、 CONFIG.SYS ファイルの LIBPATH 変数によって指定されます。 非分離ストアード・プロシージャーは、 sqllib\dll\unfenced ディレクトリーにあります。

  2. ライブラリーまたは関数が見つからない場合、procedure-name を使用して、 一致するプロシージャーがあるかどうか 定義済みプロシージャー (SYSCAT.PROCEDURES の) が探索されます。 一致するプロシージャーは、以下の手順で決定されます。

    1. カタログ (SYSCAT.PROCEDURES) から、 PROCNAME が指定の procedure-name と一致し、 PROCSCHEMA が SQL パス (CURRENT PATH 特殊レジスター) 内のスキーマ名であるプロシージャーを見つけます。 スキーマ名が明示的に指定されている場合、SQL パスは無視され、 指定されたスキーマ名のプロシージャーのみが考慮されます。
    2. 次に、CALL ステートメントで指定された引き数の数と同数のパラメーターを持たないプロシージャーを すべて除去します。
    3. 残りのプロシージャーから、SQL パスの最初のプロシージャーを選択します。
    4. ステップ 2 の後で関数が残っていない場合は、エラー (SQLSTATE 42884) が戻されます。

    プロシージャーが選択されると、 DB2 は外部名によって定義されたそのプロシージャーを呼び出します。

procedure-library!function-name
感嘆符 (!) は、ストアード・プロシージャーのライブラリー名と関数名との間の区切り文字です。 たとえば、proclib!func と指定した場合は、 proclib がメモリーにロードされ、 そのライブラリー中の関数 func が実行されます。 これによって、1 つのストアード・プロシージャー・ライブラリーの中に 複数の関数を入れることができるようになります。

procedure-name の部分で説明したように、 ストアード・プロシージャー・ライブラリーは、 ディレクトリーに入れるか、あるいは LIBPATH 変数で指定されます。

absolute-path!function-name
absolute-path (絶対パス) には、 ストアード・プロシージャー・ライブラリーまでのフルパス名を指定します。

たとえば、UNIX 系システムの場合に、/u/terry/proclib!func が指定されると、 ストアード・プロシージャー・ライブラリーの proclib が ディレクトリー /u/terry から取り出され、 そのライブラリー内の関数 func が実行されます。

OS/2 の場合、d:\terry\proclib!func を指定すると、 データベース・マネージャーは d:\terry\proclib ディレクトリーから func.dll ファイルをロードします。

いずれの場合も、暗黙のフルパスまたは明示指定のフルパスを含むプロシージャー名の全体の長さは、 254 バイトを超えてはなりません。

DB2 ユニバーサル・データベース (OS/390 版) (V4.1 以降) サーバーの場合
暗黙のまたは明示指定の 3 つの部分からなる名前。 次の各部分からなります。

上位:
プロシージャーが保管されているサーバーのロケーション名。

中央:
SYSPROC

下位:
SYSIBM.SYSPROCEDURES カタログ表の PROCEDURE 列の値。

DB2 AS/400 用 (V3.1 以降) サーバーの場合
外部プログラム名は、 procedure-name と同じであることが前提になります。

移植性を保つため、 procedure-name は、8 バイト以下の単一トークンとして指定する必要があります。

(host-variable,...)
それぞれの host-variable (ホスト変数) の指定は、CALL のパラメーターです。 CALL の n 番目のパラメーターは、 サーバーのストアード・プロシージャーの n 番目のパラメーターに対応します。

host-variable は、 クライアントとサーバー間の双方向のデータ交換に使用されるものとみなされます。 クライアントとサーバー間での不要なデータ送信を回避するため、 クライアント・アプリケーションでは、各パラメーターに標識変数を指定して、 そのパラメーターがストアード・プロシージャーへのデータの送信に使用されない場合に その標識を -1 に設定する必要があります。 ストアード・プロシージャーは、 クライアント・アプリケーションにデータを返すために使用されないパラメーターすべてについて、 標識変数を -128 に設定する必要があります。

サーバーが DB2 ユニバーサル・データベースの場合、パラメーターのデータ・タイプは、 クライアントとサーバーの両方のプログラムで一致している必要があります。 62

USING DESCRIPTOR descriptor-name
ホスト変数の有効な記述を含む SQLDA を指定します。 n 番目の SQLVAR 要素は、 サーバーのストアード・プロシージャーの n 番目のパラメーターに対応します。

CALL ステートメントが処理される前に、アプリケーションでは、 SQLDA 中の以下のフィールドを設定する必要があります。

各 SQLDA は、クライアントとサーバーの間の双方向のデータ交換に使用されるものとみなされます。 クライアントとサーバー間での不要なデータの送信を避けるため、 クライアント・アプリケーションでは、 ストアード・プロシージャーへのデータの送信にパラメーターが使用されない場合に、 SQLIND フィールドを -1 に設定する必要があります。 ストアード・プロシージャーは、 クライアント・アプリケーションにデータを返すために使用されないパラメーターすべてについて、 SQLIND フィールドを -128 に設定する必要があります。

例 1:

C において、TEAMWINS というプロシージャーを ACHIEVE ライブラリーから呼び出し、 ホスト変数 HV_ARGUMENT に保管されているパラメーターをそれに渡します。

   strcpy(HV_PROCNAME, "ACHIEVE!TEAMWINS");
   CALL :HV_PROCNAME (:HV_ARGUMENT);

例 2:

C において、:SALARY_PROC というプロシージャーを、 INOUT_SQLDA という名前の SQLDA を使用して呼び出します。

   struct sqlda *INOUT_SQLDA;
 
  /* Setup code for SQLDA variables goes here */
 
   CALL :SALARY_PROC 
   USING DESCRIPTOR :*INOUT_SQLDA;

例 3:

Java ストアード・プロシージャーが、 以下のステートメントを使用してデータベースに定義されています。

   CREATE PROCEDURE PARTS_ON_HAND (IN  PARTNUM  INTEGER,
                                  OUT COST     DECIMAL(7,2),
                                  OUT QUANTITY INTEGER)
                    EXTERNAL NAME 'parts!onhand'
                    LANGUAGE JAVA PARAMETER STYLE DB2GENERAL;

Java アプリケーションは、 以下のコードを使用してこのストアード・プロシージャーを呼び出します。

  ... 
  CallableStatement stpCall ;
 
  String sql = "CALL PARTS_ON_HAND ( ?,?,? )" ;
 
  stpCall = con.prepareCall( sql ) ; /* con is the connection */
 
  stpCall.setInt( 1, variable1 ) ;
  stpCall.setBigDecimal( 2, variable2 ) ;
  stpCall.setInt( 3, variable3 ) ;
 
  stpCall.registerOutParameter( 2, Types.DECIMAL, 2 ) ;
  stpCall.registerOutParameter( 3, Types.INTEGER ) ;
 
  stpCall.execute() ;
 
  variable2 = stpCall.getBigDecimal(2) ;
  variable3 = stpCall.getInt(3) ;
  ...  

このアプリケーションのコード部分は、 クラス parts の Java メソッド onhand を呼び出します。 これは、CALL ステートメントで指定されたプロシージャー名がデータベースで検出され、 外部名 'parts!onhand' を持っているためです。


脚注:

62
DB2 ユニバーサル・データベース (OS/390 版) サーバーと DB2 ユニバーサル・データベース (AS/400 版) サーバーでは、 ストアード・プロシージャーの呼び出し時に、 互換性のあるデータ・タイプの間での変換がサポートされています。 たとえば、クライアント・プログラムが INTEGER データ・タイプを使用し、 ストアード・プロシージャーが FLOAT を予期している場合、 サーバーはそのプロシージャーの呼び出しに先立って、INTEGER の値を FLOAT に変換します。


[ ページのトップ | 前ページ | 次ページ | 目次 | 索引 ]