データベースに保管されたプロシージャーを呼び出します。 たとえば、ストアード・プロシージャーは、データベースの位置で実行されて、 クライアント・アプリケーションにデータを戻します。
SQL CALL ステートメントを使用するプログラムは、 クライアントとサーバーの 2 つの部分で実行されるように設計されます。 データベースのサーバー・プロシージャーは、 クライアント・アプリケーションと同じトランザクション内で実行されます。 クライアント・アプリケーションとストアード・プロシージャーが同じ区分にある場合、 ストアード・プロシージャーはローカルに実行されます。
呼び出し
このステートメントは、アプリケーション・プログラムに組み込む方法のみ可能です。 これは、動的に準備できない実行可能ステートメントです。 ただし、プロシージャー名はホスト名によって指定することができます。 これは、USING DESCRIPTOR 文節の使用とを組み合わせることによって、 プロシージャー名とパラメーター・リストの両方を実行時に容易することができます。 これにより、動的準備が可能なステートメントと同じ効果が得られます。
許可
許可の規則は、プロシージャーが保管されているサーバーによって異なります。
構文
>>-CALL----+-procedure-name-+-----------------------------------> '-host-variable--' >-----+---------------------------------------+---------------->< +-(--+---------------------------+---)--+ | | .-,--------------------. | | | | V (1) | | | | '----host-variable--------+-' | '-USING--DESCRIPTOR--descriptor-name----'
注:
説明
procedure-name を指定する場合、 それは 254 バイト以下の通常識別子でなければなりません。 通常識別子だけを指定できるので、 ブランクや特殊文字を含めることができず、値は大文字に変換されます。 したがって、小文字名、ブランク、または特殊文字を使用する必要がある場合は、 名前を host-variable (ホスト変数) によって指定する必要があります。
host-variable が指定されている場合、 それは、長さ属性が 254 バイト以下の文字ストリング変数でなければならず、 標識変数を含めることはできません。 値は大文字に変換されないことに注意してください。procedure-name は左そろえでなければなりません。
プロシージャー名は、いくつかの形式のいずれかを使用して指定できます。 サポートされる形式は、プロシージャーが保管されているサーバーによって異なります。
UNIX 系システムの場合、DB2 サーバーは、 デフォルト・ディレクトリーの sqllib/function から ストアード・プロシージャー・ライブラリーを検索します。 非分離ストアード・プロシージャーは、 sqllib/function/unfenced ディレクトリーにあります。
OS/2 では、ストアード・プロシージャーの位置は、 CONFIG.SYS ファイルの LIBPATH 変数によって指定されます。 非分離ストアード・プロシージャーは、 sqllib\dll\unfenced ディレクトリーにあります。
プロシージャーが選択されると、 DB2 は外部名によって定義されたそのプロシージャーを呼び出します。
procedure-name の部分で説明したように、 ストアード・プロシージャー・ライブラリーは、 ディレクトリーに入れるか、あるいは LIBPATH 変数で指定されます。
たとえば、UNIX 系システムの場合に、/u/terry/proclib!func が指定されると、 ストアード・プロシージャー・ライブラリーの proclib が ディレクトリー /u/terry から取り出され、 そのライブラリー内の関数 func が実行されます。
OS/2 の場合、d:\terry\proclib!func を指定すると、 データベース・マネージャーは d:\terry\proclib ディレクトリーから func.dll ファイルをロードします。
いずれの場合も、暗黙のフルパスまたは明示指定のフルパスを含むプロシージャー名の全体の長さは、 254 バイトを超えてはなりません。
移植性を保つため、 procedure-name は、8 バイト以下の単一トークンとして指定する必要があります。
各 host-variable は、 クライアントとサーバー間の双方向のデータ交換に使用されるものとみなされます。 クライアントとサーバー間での不要なデータ送信を回避するため、 クライアント・アプリケーションでは、各パラメーターに標識変数を指定して、 そのパラメーターがストアード・プロシージャーへのデータの送信に使用されない場合に その標識を -1 に設定する必要があります。 ストアード・プロシージャーは、 クライアント・アプリケーションにデータを返すために使用されないパラメーターすべてについて、 標識変数を -128 に設定する必要があります。
サーバーが DB2 ユニバーサル・データベースの場合、パラメーターのデータ・タイプは、 クライアントとサーバーの両方のプログラムで一致している必要があります。 62
CALL ステートメントが処理される前に、アプリケーションでは、 SQLDA 中の以下のフィールドを設定する必要があります。
渡される各 2 次 SQLVAR 要素の次のフィールドは、初期化しておく必要があります。
各 SQLDA は、クライアントとサーバーの間の双方向のデータ交換に使用されるものとみなされます。 クライアントとサーバー間での不要なデータの送信を避けるため、 クライアント・アプリケーションでは、 ストアード・プロシージャーへのデータの送信にパラメーターが使用されない場合に、 SQLIND フィールドを -1 に設定する必要があります。 ストアード・プロシージャーは、 クライアント・アプリケーションにデータを返すために使用されないパラメーターすべてについて、 SQLIND フィールドを -128 に設定する必要があります。
クライアントとサーバー・アプリケーションで、 SQLDA から LOB データを指定して、SQLVAR 項目数の 2 倍を割り振る必要があります。
LOB データ・タイプは、DB2 バージョン 2 からストアード・プロシージャーでサポートされています。 LOB データ・タイプは、それより下位レベルのクライアントまたはサーバーでは、 まったくサポートされていません。
SQL プロシージャーが RETURN ステートメントを状況値とともに正常に発行すると、 この値が SQLCA の最初の SQLERRD フィールドに戻されます。 SQL プロシージャーで CALL ステートメントが発行される場合、 GET DIAGNOSTICS ステートメントを使用して RETURN_STATUS 値を検索します。 SQLSTATE がエラーを示す場合は、値は -1 になります。
クライアント・アプリケーション・プログラムが CLI を使用して作成されている場合、 結果セットをクライアント・アプリケーションに直接戻すことができます。 ストアード・プロシージャーは、 結果セットにカーソルを宣言して、その結果セットでカーソルをオープンし、 プロシージャー終了時にカーソルをオープンしたままにすることによって、 結果セットを戻すよう指定します。
CLI によって呼び出されたプロシージャーの終了時には、
詳細については、アプリケーション開発の手引き および コール・レベル・インターフェースの手引きおよび解説書 を参照してください。
一般に、CALL ステートメントは、既存の DARI プロシージャーでは機能しません。 詳細については、アプリケーション開発の手引き を参照してください。
呼び出し側の特殊レジスターの設定値は、 起動時にストアード・プロシージャーに継承され、呼び出し側に戻されるとただちに復元されます。 ストアード・プロシージャー内で特殊レジスターを変更してもかまいませんが、 その変更で呼び出し側に影響を与えることはありません。 ただし、既存のストアード・プロシージャー (パラメーター・スタイル DB2DARI で定義されているか、 またはデフォルト・ライブラリーにあるもの) の場合はそうではなく、 プロシージャー内で特殊レジスターに対して加えた変更は、呼び出し側の設定値になります。
例
例 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' を持っているためです。