我如何使用select in loop继续when语句?

时间:2019-01-24 17:37:45

标签: sql oracle plsql

当我在查询中发现多个结果时,我想继续执行oracle sql循环-所以我的简化代码:

declare
   cursor foo_cursor select * from foo_table;
   foo foo_cursor%ROWTYPE;
begin 
   open foo_cursor;
   loop 
      fetch foo_cursor into foo;
      exit when foo_cursor%NOTFOUND;
      continue when ( -- the next query has entries or an entry, 
                      -- but how do I do this?
         select count(*) from bar_table where bar_column=foo.foo_column
             group by bar_column having count(1)>1;
      )
      insert into uninterresting_table (some_column) VALUES
          (foo.foo_column);
    end loop;
    close foo_cursor;
end;

3 个答案:

答案 0 :(得分:2)

FOO_TABLE中至少存在两个相关记录时,您似乎只想对BAR_TABLE中的记录进行操作。您可以更改foo_cursor的定义以考虑该要求,如下所示。这样,您无需每次都反复检查BAR_TABLE中是否存在记录。

declare
   cursor foo_cursor is 
   select * 
     from foo_table foo
    where exists (select 1 from bar_table bar
                   where bar.bar_column = foo.foo_column
                  having count(*) > 1);
   foo foo_cursor%ROWTYPE;
begin 
   open foo_cursor;
   loop 
      fetch foo_cursor into foo;
      exit when foo_cursor%NOTFOUND;
      insert into uninteresting_table (some_column) VALUES
          (foo.foo_column);
    end loop;
    close foo_cursor;
end;
/

另一方面,如果您要跳过FOO_TABLE中已经在BAR_TABLE中有两个或多个记录的记录,则只需反转存在检查,其他所有都将相同:< / p>

declare
   cursor foo_cursor is 
   select * 
     from foo_table foo
    where NOT exists (select 1 from bar_table bar
                       where bar.bar_column = foo.foo_column
                      having count(*) > 1);
   foo foo_cursor%ROWTYPE;
begin 
   open foo_cursor;
   loop 
      fetch foo_cursor into foo;
      exit when foo_cursor%NOTFOUND;
      insert into uninteresting_table (some_column) VALUES
          (foo.foo_column);
    end loop;
    close foo_cursor;
end;
/

如果您要处理FOO_TABLE中的所有记录,但是当BAR_TABLE中有两个或更多记录时要执行其他操作,则仍然可以通过更改foo_cursor来做到这一点:< / p>

declare
   cursor foo_cursor is 
   select foo.* 
        , case when exists (select 1 from bar_table bar
                             where bar.bar_column = foo.foo_column
                            having count(*) > 1)
               then 'Y'
               else 'N'
          end has_two_or_more
     from foo_table foo;
   foo foo_cursor%ROWTYPE;
begin 
   open foo_cursor;
   loop 
      fetch foo_cursor into foo;
      exit when foo_cursor%NOTFOUND;
      continue when foo.has_two_or_more = 'Y';
      insert into uninteresting_table (some_column) VALUES
          (foo.foo_column);
    end loop;
    close foo_cursor;
end;
/

答案 1 :(得分:1)

  

如果[选择具有...一个和多个条目],我想进入下一个迭代,否则在该迭代中做更多的事情。

如果bar_table中没有记录,则您想进行更多处理,否则就跳过该处理。有一种方法可以做到:goto

哦,是:)

declare
   cursor foo_cursor select * from foo_table;
   foo foo_cursor%ROWTYPE;
   n pls_integer;
begin 
   open foo_cursor;
   loop 
      fetch foo_cursor into foo;
      exit when foo_cursor%NOTFOUND;
      select count(*) into n
      from bar_table 
      where bar_column=foo.foo_column
      group by bar_column having count(1)>1;

      if n > 0 then
         goto skip_point;
      end if;

      insert into uninterresting_table (some_column) VALUES
          (foo.foo_column);

      << skip_point >>
    end loop;
    close foo_cursor;
end;

很显然,您可以将整个可跳过部分放在IF .. ELSE语句的分支中,但是这样做的乐趣何在?

答案 2 :(得分:1)

所以感谢@APC和@Sentinel-我仍然使我的版本正常工作,但是您的回答给了我正确的方向:

declare
   cursor foo_cursor select * from foo_table;
   foo foo_cursor%ROWTYPE;
   n pls_integer
begin 
   open foo_cursor;
   loop 
      fetch foo_cursor into foo;
      exit when foo_cursor%NOTFOUND;
      begin
         select count(1) into n from bar_table where bar_column=foo.foo_column
             group by bar_column;
         exception when NO_DATA_FOUND then continue;
      end
      continue when (n>1);
      insert into uninterresting_table (some_column) VALUES
          (foo.foo_column);
      -- do some more stuff
    end loop;
    close foo_cursor;
end;
```