2016-08-26 3 views
0

私はPL/SQLの新機能であり、明示的なカーソルを使用してデータベースFLEX_PANEL_INSPECTIONSを反復しようとしています。明示的なカーソルを使用してデータベースから各行を順番にフェッチしたいと思います。ランダムに生成された行の「パネル」の「ステータス」に応じて、if/elseステートメント内に新しいステータス値を割り当てます。パネルのステータスはランダムですがブール値ですが、1または0です。 しかし、DBMSの出力を見ると、フェッチではデータベースからすべての値が取得されるわけではなく、ステータス値が1私は以下のコアコードを含んでいます。 誰かが解決策を見つける手助けをしたり、私の問題の根本的な原因を説明できれば、非常に感謝します。PL/SQLで明示カーソルがデータベースから特定の行のみをフェッチするのはなぜですか?

create or replace procedure FLEX_SUMMARY_STATUS_PROCEDURE as 

old_panel_status number; 
new_panel_status number; 

cursor panel_cursor is 
    select FLEX_PANEL_STATUS 
    from FLEX_PANEL_INSPECTIONS; 

begin 

    open panel_cursor; 
    loop 

     fetch panel_cursor into old_panel_status; 
     exit when panel_cursor%notfound; 

     if old_panel_status = 0 
      then new_panel_status := 2; 
     elsif old_panel_status = 1 
      then new_panel_status := 3; 
     --More conditional loops follow (but are irrelevant for this question). 

     dbms_output.put_line(old_panel_status); 
     --Test output 
     --This displays all of the 1's that were randomly generated in the original table. 
     --It does not display any of the 0's that were generated. 

     end if; 
    end loop; 

close panel_cursor; 
close sensor_cursor; 

end FLEX_SUMMARY_STATUS_PROCEDURE; 
/
+2

あなたは 'でDBMS_OUTPUT old_panel_status = 1 'の場合には、ブロック!多分、 'end if;' UPとdbms_ouputの前に移動しますか? – Mike

+2

'dbms_output'は* else *節の中にあります。したがって、status = 1のものだけが出力されます。コード識別は、if/then/elseの外にあることを示します。 – Codo

+0

旧式のopen/loop/fetch/exit構文の使用をやめてください。それは冗長で問題を引き起こします。代わりに、はるかにエレガントな 'FOR rec INカーソルループ... END LOOP'を使用してください。 – Codo

答えて

1

追加のelseif句を削除するときに、あなたがミスをしなかった場合、問題はあなたのDBMS_OUTPUT.PUT_LINEの場所です。

これはelse部分の内側にあるため、この句が呼び出されたときにのみトリガされます。 END IFの下に移動し、適切なインデントを使用するようにしてください。そうすることで、そのような方法を簡単に見つけることができます。既に受け入れ答えに固定されたメイン誤差に加えて、

create or replace procedure FLEX_SUMMARY_STATUS_PROCEDURE as 

old_panel_status number; 
new_panel_status number; 

cursor panel_cursor is 
    select FLEX_PANEL_STATUS 
    from FLEX_PANEL_INSPECTIONS; 

begin 

    open panel_cursor; 
    loop 

     fetch panel_cursor into old_panel_status; 
     exit when panel_cursor%notfound; 

     if old_panel_status = 0 
      then new_panel_status := 2; 
     elsif old_panel_status = 1 
      then new_panel_status := 3; 
     --More conditional loops follow (but are irrelevant for this question) 
     end if; 

    dbms_output.put_line(old_panel_status); 

    end loop; 

    close panel_cursor; 
    close sensor_cursor; 

end FLEX_SUMMARY_STATUS_PROCEDURE; 
/
+0

ありがとうございます - 正しいインデントを表示するために元の投稿を編集しました –

2

、以下のコードは、新しいループ構造を示しています。 recの代わりに、好きな変数名を選択できます。各反復では、行が含まれます(通常は複数の列があります)。

create or replace procedure FLEX_SUMMARY_STATUS_PROCEDURE as 

new_panel_status number; 

cursor panel_cursor is 
    select FLEX_PANEL_STATUS 
    from FLEX_PANEL_INSPECTIONS; 

begin 

    for rec in panel_cursor loop 

     if rec.flex_panel_status = 0 then 
      new_panel_status := 2; 
     elsif rec.flex_panel_status = 1 then 
      new_panel_status := 3; 
     --More conditional loops follow (but are irrelevant for this question) 
     end if; 

     dbms_output.put_line(rec.flex_panel_status); 

    end loop; 

end FLEX_SUMMARY_STATUS_PROCEDURE; 
/

あなたも取り除くことができれば、あなたが好きなら、明示カーソル:

for rec in (
    select FLEX_PANEL_STATUS 
    from FLEX_PANEL_INSPECTIONS 
) loop 
+0

もっと良いです。私たちがオラクルのリリースについて話しているのであれば、カーソルFORループはオープンループ・フェッチ・イグスト・ロス・ウィル・トゥ・ザブ・ライブ構造よりも「新」であるとは思えません。 –

関連する問題