複数コネクションの切断は、CONNECT文で接続した、それぞれのコネクションに対してDISCONNECT文で行います。コネクションを切断する場合は、トランザクションは終了した状態でなければなりません。コネクションを切断せずに処理を終了すると、利用されていないコネクションが残ったままとなります。
複数コネクションを切断するプログラミングの概要を以下に示します。
[アプリケーション]
EXEC SQL CONNECT TO 'DB01' AS 'C1' ; … (1) : EXEC SQL SELECT 在庫数量,倉庫番号 INTO :H1, :H2 FROM 在庫表 … (2) WHERE 在庫数量=300; : EXEC SQL COMMIT WORK ; … (3) : EXEC SQL CONNECT TO 'DB02' AS 'C2' ; … (4) : EXEC SQL INSERT INTO 伝票(在庫カラム, 倉庫カラム) VALUES(:H1,:H2); … (5) : EXEC SQL COMMIT WORK ; … (6) : EXEC SQL DISCONNECT 'C1' ; … (7) : EXEC SQL DISCONNECT 'C2' ; … (8) : : EXEC SQL CONNECT TO 'SV3' AS 'C3' USER 'U3/PASS3' ; … (9) : EXEC SQL SELECT 在庫数量,倉庫番号 INTO :H1, :H2 FROM 在庫表1 … (10) WHERE 在庫数量=300 ; : EXEC SQL COMMIT WORK ; … (11) : EXEC SQL CONNECT TO 'SV4' AS 'C4' USER 'U4/PASS4' ; … (12) : EXEC SQL INSERT INTO 伝票1(在庫カラム,倉庫カラム) VALUES(:H1,:H2) ; … (13) : EXEC SQL COMMIT WORK ; … (14) : EXEC SQL DISCONNECT 'C3' ; … (15) : EXEC SQL DISCONNECT 'C4' ; … (16)
(1)~(8)は、ローカルアクセスの場合です。(9)~(16)は、リモートアクセスの場合です。
(1) 1回目のCONNECT文により“DB01”に対して“C1”のコネクションを接続します。
(2) “DB01”の在庫表から単一行SELECT文で在庫数量と倉庫番号を取り出します。
(3) (2)の操作に対して、トランザクションを終了します。
(4) 2回目のCONNECT文により、“DB02”に対して“C2”のコネクションを接続します。
(5) “DB02”の伝票の在庫カラムと倉庫カラムに、“DB01”から取り出した在庫数量と倉庫番号を追加します。
(6) (5)の操作に対して、トランザクションを終了します。
(7) “DB01”に対して“C1”のコネクションを切断します。
(8) “DB02”に対して“C2”のコネクションを切断します。
(9) 3回目のCONNECT文により、サーバ“SV3”に対して“C3”のコネクションを接続します。
(10) サーバ“SV3”の在庫表1から、単一行SELECT文で在庫数量と倉庫番号を取り出します。
(11) (10)の操作に対して、トランザクションを終了します。
(12) 4回目のCONNECT文により、サーバ“SV4”に対して“C4”のコネクションを接続します。
(13) サーバ“SV4”の伝票1の在庫カラムと倉庫カラムに、サーバ“SV3”から取り出した在庫数量と倉庫番号を追加します。
(14) (13)の操作に対して、トランザクションを終了します。
(15) サーバ“SV3”に対して“C3”のコネクションを切断します。
(16) サーバ“SV4”に対して“C4”のコネクションを切断します。
カーソルをオープンしたあとに、複数のコネクションにまたがって、同じカーソルの操作を行うことはできません。
ほかのコネクションで同じカーソルを操作するには、カーソルをクローズしたあとでなければなりません。このカーソル操作の例として、誤った指定例および正しいカーソル操作の例を以下に示します。
誤ったカーソル操作の場合
[アプリケーション]
EXEC SQL DECLARE CUR1 CURSOR FOR SELECT 在庫数量 FROM 在庫表 ; … (1) EXEC SQL CONNECT TO 'DB01' AS 'C1' ; … (2) EXEC SQL OPEN CUR1 ; … (3) EXEC SQL CONNECT TO 'DB02' AS 'C2' ; … (4) EXEC SQL FETCH CUR1 INTO :STOCK ; → エラー … (5)
(1) カーソル“CUR1”を宣言します。
(2) “DB01”に対して“C1”のコネクションを接続します。
(3) “DB01”に対して、カーソル“CUR1”をオープンします。
(4) “DB02”に対して“C2”のコネクションを接続します。
(5) “DB02”に対して、カーソル“CUR1”をFETCHすると、すでに“DB01”に対してカーソルがオープンしているため、エラーとなります。
正しいカーソル操作の場合
[アプリケーション]
EXEC SQL DECLARE CUR1 CURSOR FOR SELECT 在庫数量 FROM 在庫表 ; … (1) EXEC SQL CONNECT TO 'DB01' AS 'C1' ; … (2) EXEC SQL OPEN CUR1 ; … (3) : EXEC SQL CLOSE CUR1 ; … (4) EXEC SQL COMMIT WORK ; … (5) EXEC SQL CONNECT TO 'DB02' AS 'C2' ; … (6) EXEC SQL OPEN CUR1 ; : EXEC SQL CLOSE CUR1 ;
(1) カーソル“CUR1”を宣言します。
(2) “DB01”に対して“C1”のコネクションを接続します。
(3) “DB01”に対して、カーソル“CUR1”をオープンします。
(4) カーソル“CUR1”をクローズします。
(5) (3)でオープンしたカーソルを使用して更新操作を行った場合、トランザクションを終了します。
(6) “DB02”にコネクションを接続して、カーソル“CUR1”をオープンします。
1つのトランザクションで、複数のコネクションに対してデータベースを更新するSQL文は実行できません。複数のコネクションでデータを更新する場合は、トランザクションを別々にする必要があります。
この更新操作の例として、誤った指定例および正しい更新操作の例を以下に示します。
誤った更新操作の場合
[アプリケーション]
EXEC SQL CONNECT TO 'DB01' AS 'C1' ; … (1) EXEC SQL CONNECT TO 'DB02' AS 'C2' ; … (2) EXEC SQL UPDATE 在庫表 SET 在庫数量=300 WHERE 品番号=10; … (3) EXEC SQL SET CONNECTION 'C1' ; … (4) EXEC SQL UPDATE 支店表 SET 社員数=100 WHERE 支店番号=80; → エラー … (5)
(1) “DB01”に対して“C1”のコネクションを接続します。
(2) “DB02”に対して“C2”のコネクションを接続します。この場合のコネクションが現コネクションになります。
(3) “DB02”に対して更新操作を行います。
(4) “DB01”に現コネクションを変更します。
(5) “DB02”に対する更新操作のトランザクションが終了していないため、“DB01”に対する更新操作はエラーとなります。
正しい更新操作の場合
[アプリケーション]
EXEC SQL CONNECT TO 'DB01' AS 'C1' ; EXEC SQL CONNECT TO 'DB02' AS 'C2' ; EXEC SQL UPDATE 在庫表 SET 在庫数量=300 WHERE 品番号=10; EXEC SQL COMMIT WORK ; … (1) EXEC SQL SET CONNECTION 'C1' ; … (2) EXEC SQL UPDATE 支店表 SET 社員数=100 WHERE 支店番号=80; EXEC SQL COMMIT WORK ;
(1) “DB02”に対しての更新操作のトランザクションを終了します。
(2) “DB01”に現コネクションを変更して、“DB01”に対して更新操作を行います。
1つのトランザクションで、複数のコネクションに対して、データベースの定義変更を行うことはできません。