 |
|
| 前のページ 1 2 |
 |
| フェッチ |
上述したカーソル属性同様、PostgreSQLではFETCH文の振る舞いも異なります。まずはOracleの例を見てください(リスト23)
|
DECLARE CURSOR C1 IS SELECT 顧客名 FROM 顧客マスタ; customer VARCHAR2(20); BEGIN OPEN C1; FETCH C1 INTO customer; DBMS_OUTPUT.PUT_LINE( '顧客名= ' || customer ); FETCH C1 INTO customer; DBMS_OUTPUT.PUT_LINE( '顧客名= ' || customer ); FETCH C1 INTO customer; DBMS_OUTPUT.PUT_LINE( '顧客名= ' || customer ); FETCH C1 INTO customer; DBMS_OUTPUT.PUT_LINE( '顧客名= ' || customer ); FETCH C1 INTO customer; DBMS_OUTPUT.PUT_LINE( '顧客名= ' || customer ); FETCH C1 INTO customer; DBMS_OUTPUT.PUT_LINE( '顧客名= ' || customer ); CLOSE C1; END; |
リスト23:OracleのFETCH文の例
|
Oracleでは最後の行に達した後も、FETCH文のターゲット変数がNULLになりません。実行結果を見てみましょう(図16)。
|
顧客名= (株)ワイキキソフト 顧客名= 鈴木商事 顧客名= 斎藤模型店 顧客名= マクロハード 顧客名= (株)ランヌ 顧客名= (株)ランヌ
PL/SQLプロシージャが正常に完了しました。 |
図16:リスト23の実行結果
|
それに比べて、PostgreSQLでは最後の行に達した後は、FETCH文のターゲット変数にNULLが代入されます(リスト24)。
|
CREATE OR REPLACE FUNCTION TEST_FETCH() RETURNS VOID AS ' DECLARE C1 CURSOR IS SELECT 顧客名 FROM 顧客マスタ; customer VARCHAR(20); BEGIN OPEN C1; FETCH C1 INTO customer; RAISE INFO ''顧客名= %'', customer; FETCH C1 INTO customer; RAISE INFO ''顧客名= %'', customer; FETCH C1 INTO customer; RAISE INFO ''顧客名= %'', customer; FETCH C1 INTO customer; RAISE INFO ''顧客名= %'', customer; FETCH C1 INTO customer; RAISE INFO ''顧客名= %'', customer; FETCH C1 INTO customer; RAISE INFO ''顧客名= %'', customer; CLOSE C1; RETURN; END; ' LANGUAGE 'plpgsql';
SELECT TEST_FETCH(); |
リスト24:PostgreSQLのFETCH文の例
|
さきほどのOracleの実行結果(図16)と図17を比べてください。
|
INFO: 顧客名= (株)ワイキキソフト INFO: 顧客名= 鈴木商事 INFO: 顧客名= 斎藤模型店 INFO: 顧客名= マクロハード INFO: 顧客名= (株)ランヌ INFO: 顧客名= <NULL> test_fetch ------------
(1 row) |
図17:リスト24の実行結果
|
この微妙な振る舞いの違いがあるため、PostgreSQLではリスト25にあるような、Oracleでよく使われるループの書き方ができません。
|
DECLARE CURSOR C1 IS SELECT 顧客名 FROM 顧客マスタ ORDER BY 顧客ID; NAME VARCHAR2(20); BEGIN OPEN C1; LOOP FETCH C1 INTO NAME; EXIT WHEN C1%NOTFOUND; END LOOP; DBMS_OUTPUT.PUT_LINE( '顧客IDが一番大きい顧客= ' || NAME ); CLOSE C1; END; |
リスト25:Oracleでのループ例
|
リスト25の実行結果は次のようになります。
|
顧客IDが一番大きい顧客 = (株)ランヌ |
 |
このため、PostgreSQLではリスト26のようにフェッチ結果の変数への代入を2段階に分ける必要があります。
|
CREATE OR REPLACE FUNCTION TEST_FETCH2() RETURNS VOID AS ' DECLARE C1 CURSOR IS SELECT 顧客名 FROM 顧客マスタ ORDER BY 顧客ID; NAME TEXT; _NAME TEXT; BEGIN OPEN C1; LOOP FETCH C1 INTO _NAME; IF NOT FOUND THEN EXIT; ELSE NAME := _NAME; END IF; END LOOP; RAISE INFO ''顧客IDが一番大きい顧客= %'', NAME; CLOSE C1; RETURN; END; ' LANGUAGE 'plpgsql';
SELECT TEST_FETCH2(); |
リスト26:PostgreSQLでのフェッチ結果の代入例
|
これは、PostgreSQLでは次のように単純に変換してしまうと、ループを抜けた後のNAME変数の中身が最後のフェッチ内容ではなくNULLになってしまうためです。
|
LOOP FETCH C1 INTO NAME; EXIT WHEN NOT FOUND; END LOOP; RAISE INFO ''顧客IDが一番大きい顧客= %'', NAME; |
 |
前のページ 1 2
|

|
 |

| 著者プロフィール 奥畑 裕樹(OKUHATA, Hiroki) Javaとオープンソース技術を得意とする技術コンサルタント。最近のテーマは、ソフトウェア開発の全体最適をはかること。気が付けば、10才のときにプログラミングを始めて以来、常に何かを作っている…。
|
|
 |
|
 |
|