为什么我的显式游标只从PL / SQL中的数据库中获取特定的行?

时间:2016-08-26 10:29:07

标签: sql oracle plsql cursor fetch

我是PL / SQL的新手,我正在尝试使用显式游标迭代我的数据库FLEX_PANEL_INSPECTIONS。我想依次使用显式光标从数据库中获取每一行,具体取决于随机生成的状态'一个给定的小组'在行中,在if / else语句中为面板指定一个新的状态值。面板的状态是随机的但是布尔值 - 它是1或0。 但是,当我查看DBMS输出时,我注意到fetch不会从数据库中检索所有值 - 只有那些状态值为1的值。我已经在下面包含了核心代码。 如果有人能够帮我找到解决方案,或者解释我问题的根本原因,我将非常感激!谢谢!

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 个答案:

答案 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

答案 1 :(得分: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;
/