2017-05-03 36 views
1

DB2、バージョン10.5。DB2、PL/SQLおよびカーソル(IBMは独自のヘルプ・ページに従いません)

私のカーソルが、このようなものです:

declare stat cursor for select record_type, sequence_code from my_status fetch first 10 rows only; 

使用して、それを横断しようとするIBM Webページに記載されているような構造、例えばFOR

for s in stat do 
    call dbms_output.put_line ('In the cursor loop'); 
end for; 

DB21034Eそれは 有効なコマンド行プロセッサーのコマンドではなかったため、コマンドはSQLステートメントとして処理されました。 SQL処理中に戻りました: SQL0104N "rst 10 rows only; "の後に予期しないトークン "for"が見つかりました。予想されるトークンには以下が含まれます: "" LINE NUMBER = 9。 SQLSTATE = 42601。

私は、明示的にオープンしてループ内でフェッチを試みましたが、それはうまくいったのですが、それが永久に続きました(つまり、エラーが発生せず、10レコードの最後に達したときに中止しました)ループの明示的なカウンターに入れていなかった。データからフィールドを表示することは、だから、ループ内 "STAT%が見つかった場合、" を追加しようとした1、2、3 .... 9、10、10、10、10、10

をループした証明しました

DB21034E有効なコマンドラインプロセッサコマンドが ではないため、このコマンドはSQL文として処理されました。 SQL処理中に戻されました。 SQL0104N "ence_code; if stat"の後に予期しないトークン "%"が見つかりました。 予想されるトークンには、「IS」が含まれます。 LINE NUMBER = 24です。 SQLSTATE = 42601

は私もFOUND/NOTFOUNDの状態を確認するためにCASE文を試してみましたが、同様のエラーを得た:それは有効な なかったため、コマンドはSQLステートメントとして処理されました

case when stat%NOTFOUND then 
    call dbms_output.put_line('In case'); 
end case; 

DB21034Eコマンドラインプロセッサコマンド。 SQL処理中に戻りました。 SQL0104N "statの場合"の後に予期しないトークン "%"が見つかりました。 予想されるトークンには、「IN」が含まれます。 LINE NUMBER = 30です。それは 有効なコマンド行プロセッサーのコマンドではなかったため、コマンドはSQLステートメントとして処理されました

DB21034E:stat.%NOTFOUND(ちょうど%までの期間)に、それを変更するSQLSTATE = 42601

は私にこれを得ました。 SQL処理中に戻されました。 SQL0104N " "の場合、予期しないトークン "stat。%NOTFOUND"が見つかりました。予想されるトークンには以下が含まれます: "" LINE NUMBER = 30です。 SQLSTATE = 42601

そして、私は "exit when stat%NOTFOUND"をIBMサポートページからそのまま試しました。これは私にこのような似たエラーをもたらしました:

DB21034E有効なコマンドライン・プロセッサー・コマンド ではないため、このコマンドはSQLステートメントとして処理されました。 SQL処理中に戻されました。 SQL0104N ""に続いて予期しないトークン "EXIT"が見つかりました。 予想されるトークンには次のものがあります: "" LINE NUMBER = 23。 SQLSTATE = 42601

コメントアウトこれらの様々なビットでコードの完全な塊は、それがデータを使い果たしたときに終了することができないことを除いて正常に動作します:LUWのため

set serveroutput [email protected] 

begin 
    declare v_counter int default 0; 
    declare v_record_type char(1); 
    declare v_sequence_code int; 

    declare stat cursor for select record_type, sequence_code from my_status fetch first 10 rows only; 

    -- for s in stat do 
    --  call dbms_output.put_line ('In the cursor loop'); 
    -- end for; 

    open stat; 

    fetch from stat into v_record_type, v_Sequence_code; 

    set v_counter = 0; 
    while v_counter < 12 do 
     call dbms_output.put_line('in loop'); 
     call dbms_output.put_line('Record: '||v_record_type||' '||v_sequence_code); 
     set v_counter = v_counter + 1; 
     call dbms_output.put_line ('Counter: '||v_counter); 
     fetch from stat into v_record_type, v_sequence_code; 
     --if stat%FOUND then 
     -- call dbms_output.put_line ('Yay, found!'); 
     --end if; 
    --if stat%NOTFOUND then 
    --  exit; 
    --end if; 
    --case when stat%NOTFOUND then 
    -- call dbms_output.put_line('In case'); 
    --end case; 
    --EXIT WHEN stat%NOTFOUND; 
    end while; 
    close stat; 
END -- end procedure 
@ 
set serveroutput [email protected] 
+0

1つのブロックにDB2 SQL PLとPL/SQL構文を混在させています。あなたはそれらの1つを選んでそれに固執する必要があります。 – mustaccio

+0

私は、そのコメントで正しい道を導いてくれたと思います。私はOracle PL/SQLのバックグラウンドからの違いを認識していませんでした。小文字のコードが動作します:set serveroutput on @ begin for mystat cursor for select record_type、sequence_code from my_status最初の2行だけをフェッチする do dbms_output.put_line( 'in loop:' || s。 record_type || '' || s.sequence_code); end for; end @ – JOATMON

+0

私は、IBMの文書はうまくいかないと言っています。 "for"構造体はPL/SQLページの下に表示されます。 WHILE構造のドキュメントは間違っています。 – JOATMON

答えて

1

DB2は、2つの異なるPSMの方言サポートしています。ネイティブDB2 SQL PLとオラクル互換PL/SQL

SQL PLはすべて存在しているので、その文は通常のSQLリファレンスでドキュメントに記載されています。 PL/SQLサポートは2010年ごろに追加され、その構文は別のセクションで説明されています(上記のリンクを参照)。プログラムブロックは2つの方言のどちらかしか使用できませんが、両方を同じブロックで使用することはできませんので、2つを混在させないように注意する必要があります。多くのステートメントには構文上の相違点がありますので、使用したい方言を選択すると、マニュアルの適切なセクションを参照してください。

シンタックスの検出は、構造に基づいて自動的に行われます。 DB2 SQL PLでは、DECLAREステートメントがブロック内に表示され、PL/SQLではブロック外に表示されます。だからあなたのブロックが

BEGIN 
DECLARE something; 
... 
END 

で始まる場合、SQL PLステートメントが含まれていると仮定され、コンパイラは代わりに、PL/SQL文に遭遇した場合、それは構文エラーがスローされます。

DB2コマンド行プロセッサーを使用してプログラムを実行する場合は、SET SQLCOMPAT {DB2|PLSQL}コマンドを使用して方言を明示的に指定できます。

+0

もう一度、ありがとうございます。私はPL/SQLに準拠していると思っていたので、%FOUND構造のようなものがなぜ失敗したのかまだ分かりません(これはFORのものがコメントアウトされた時です)。しかし、私はそれについて心配しません。 OPEN/FETCHバリアントとFORバリアントはIBMのPL/SQLページにあり、多くの混乱を招いていました。 – JOATMON

+0

何が効きましたか:@ にserveroutputを設定 - コマンドを実行してください:db2 -td @ -vf test2.sql begin \t hold_record_type char(1)default ''; - 他に多くの宣言があります。 \t dbms_outputを呼び出します。イネーブル(100000); \t STATLOOP: - などの分野status_table \t \t --fetch最初の1000行から \t \tのみ \t行う - \t \tためMYSTATカーソルなどのため \t \t \t \t RECORD_TYPE、SEQUENCE_CODEを選択たくさんいくつかのインサートを別のテーブルに含むロジックのこと。 \t end for; end @ – JOATMON

関連する問題