Symfoware(R) Server RDBユーザーズガイド 応用プログラム開発編 - FUJITSU - |
目次 索引 |
サーバ上のスキーマに登録済のプロシジャルーチンを、クライアント側から呼び出して実行するには、SQL制御文のCALL文を使用します。プロシジャルーチンに引数を指定することで、外部からの入力情報によって処理制御を切り替えることができます。CALL文の引数にナル値を設定または返却する場合には、標識変数を指定します。プロシジャルーチンを使用した応用プログラムの翻訳では、sqlcc、sqlfccまたはsqlcobolコマンドに-W95オプション、-W96オプションまたは-W2000オプションを指定してください。CALL文の指定方法には図:プロシジャルーチン実行の指定方法に示すように2種類があります。
[動的SQL文(PREPARE文/EXECUTE文)での実行]
strcpy(HOST, "CALL 在庫管理.営業所別発注処理(?)"); (1) (2) EXEC SQL PREPARE STMID FROM :HOST; EXEC SQL EXECUTE STMID USING :INDATA; (3) |
(1) スキーマ名
(2) ルーチン名
(3) 引数
[静的SQL文での実行]
EXEC SQL CALL 在庫管理.営業所別発注処理 (:INDATA); (1) (2) (3) |
(1) スキーマ名
(2) ルーチン名
(3) 引数
図:ルーチン実行時のクライアントとサーバの関係に、図:定義ファイルからプロシジャルーチンを登録する例に示したプロシジャルーチン定義を実行した場合のクライアントとサーバの関係を示します。
プロシジャルーチン内の処理で取り出したデータを呼出し側の応用プログラムに返却するには、パラメタ変数を利用します。しかし、表から抽出した大量のデータを返却する場合、パラメタ変数では実現できません。このような場合、一時表を利用することで実現できます。
以下に、概要を示します。
(1) 応用プログラムからプロシジャルーチン(該当者の過去診断情報)を呼び出します。
(2) プロシジャルーチンで抽出されたデータを、一時表(該当者一時表)に格納します。
(3) プロシジャルーチンが終了します。
(4) 一時表に格納されている、プロシジャルーチン内での抽出結果を、応用プログラムに取り込みます。
CREATE PROCEDURE SCM2.該当者の過去診断情報( IN P年齢範囲1 SMALLINT, IN P年齢範囲2 SMALLINT, IN P性別 NCHAR(2), IN P血液型 CHAR(5) ) BEGIN DECLARE SQLSTATE CHAR(5); DECLARE SQLMSG CHAR(256); DECLARE S管理番号 INTEGER; -- 入力された条件に該当する、過去の患者の管理番号を抽出する DECLARE CUR01 CURSOR FOR SELECT 管理番号 FROM SCM1.患者管理表 WHERE 年齢 BETWEEN P年齢範囲1 AND P年齢範囲2 AND 性別 = P性別 AND 血液型 = P血液型; -- ハンドラ宣言 DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK WORK; -- 例外が発生した場合、ROLLBACKして終了する RESIGNAL; -- 発生した例外事象をCALL文の結果として通知する END; DECLARE CONTINUE HANDLER FOR NOT FOUND BEGIN END; -- データなし例外発生時は処理を継続する -- 最初に初期化 DELETE FROM SCM00.該当者一時表; -- 該当者の管理番号の抽出 OPEN CUR01; LOOP1:LOOP FETCH CUR01 INTO S管理番号; IF (SQLSTATE = '02000') THEN LEAVE LOOP1; END IF; -- 該当者の過去の診察情報を取り出して一時表に格納する INSERT INTO SCM00.該当者一時表 SELECT 患者名, 診察日, 担当医, 診断結果, 診断詳細, 血圧 FROM SCM1.診察結果管理 WHERE 管理番号 = S管理番号; END LOOP LOOP1; CLOSE CUR01; COMMIT WORK; END |
備考. 一時表“該当者一時表”はON COMMIT PRESERVE ROWS指定とします。
#include <stdio.h> EXEC SQL BEGIN DECLARE SECTION; short AGE1; short AGE2; char CHARACTER SET IS NCHAR SEX[5]; char BLOOD[6]; …… EXEC SQL END DECLARE SECTION; int main( ) { …… EXEC SQL WHENEVER SQLERROR GOTO :ERR_END; /* プロシジャルーチンの呼び出し */ AGE1 = 20; AGE2 = 40; strcpy(SEX, "男性"); strcpy(BLOOD, "A RH+"); EXEC SQL CALL SCM2.該当者の過去診断情報(:AGE1, :AGE2, :SEX, :BLOOD ); /* 一時表のデータを出力する */ EXEC SQL DECLARE CUR1 CURSOR FOR SELECT * FROM SCM00.該当者一時表 ORDER BY 患者名, 診察日; EXEC SQL OPEN CUR1; EXEC SQL WHENEVER NOT FOUND GOTO :LOOP_END; for (cnt = 1; ; cnt++) { EXEC SQL FETCH CUR1 INTO :D_NAME, :D_DATE, :D_DOCTOR, :D_DIAGNOSE, :D_INFO, :D_BP; printf("[%d]患者名=%s, 診察日=%s, 担当医=%s, " "診断結果=%s, 診断詳細=%s, 血圧=%s\n", cnt, D_NAME, D_DATE, D_DOCTOR, D_DIAGNOSE, D_INFO, D_BP); } LOOP_END: EXEC SQL CLOSE CUR1; …… |
目次 索引 |