40

我正在将 TSQL 存储过程迁移到 PL/SQL 并且遇到了一个问题 - Oracle 10g 中缺少 CONTINUE 关键字。

我读到Oracle 11g 有这个作为一个新特性,但不幸的是升级不是一个选项。

10g 中的 CONTINUE 有什么替代品吗?我认为将 SP 的逻辑重构为一种变通方法是不切实际的,因为我有一个外部循环、一个 IF,然后是一个嵌套的 IF,然后是该 IF 中语句块末尾的 CONTINUE。

任何帮助将不胜感激,干杯。

4

9 回答 9

58

您可以使用goto 和 labels模拟继续。

DECLARE
   done  BOOLEAN;
BEGIN
   FOR i IN 1..50 LOOP
      IF done THEN
         GOTO end_loop;
      END IF;
   <<end_loop>>  -- not allowed unless an executable statement follows
   NULL; -- add NULL statement to avoid error
   END LOOP;  -- raises an error without the previous NULL
END;
于 2008-10-07T09:44:26.477 回答
10

虽然它有点复杂而且只是假的,但您可以通过这种方式使用异常:

DECLARE
  i NUMBER :=0;
  my_ex exception;
BEGIN
  FOR i IN 1..10
  LOOP
      BEGIN
         IF i = 5 THEN
            raise my_ex;
         END IF;
         DBMS_OUTPUT.PUT_LINE (i);
      EXCEPTION WHEN my_ex THEN
         NULL;
      END;
  END LOOP;

END;
于 2009-03-12T05:11:08.503 回答
7

事实上,PL SQL 确实有一些东西可以代替 CONTINUE。您所要做的就是在循环中添加一个标签(名称):

declare
   i integer;
begin
   i := 0;

   <<My_Small_Loop>>loop

      i := i + 1;
      if i <= 3 then goto My_Small_Loop; end if; -- => means continue

      exit;

   end loop;
end;
于 2011-08-22T15:12:55.623 回答
6

对于未来的搜索,他们在 oracle 11g 中添加了一条continue语句,可以这样使用:

    SQL> BEGIN
  2     FOR i IN 1 .. 5 LOOP
  3        IF i IN (2,4) THEN
  4           CONTINUE;
  5        END IF;
  6        DBMS_OUTPUT.PUT_LINE('Reached on line ' || TO_CHAR(i));
  7     END LOOP;
  8  END;
  9  /
Reached on line 1
Reached on line 3
Reached on line 5

PL/SQL procedure successfully completed.
于 2013-07-11T08:25:30.317 回答
5

它在 10g 中不可用,但它是11G 中的新功能

于 2008-10-28T08:51:26.553 回答
4

您能否将 IF 重构为一个函数,并在适当的位置返回(必要时提前)。然后控制流将在正确的位置进入循环。

那有意义吗?

于 2008-10-07T09:37:43.433 回答
2

不完全优雅,但简单:

DECLARE
   done  BOOLEAN;
BEGIN
   FOR i IN 1..50 LOOP
      IF done THEN
         NULL;
      ELSE
         <do loop stuff>;
      END IF;
   END LOOP; 
END;
于 2009-09-04T16:37:36.407 回答
1

在 Oracle 中,有一个类似的语句称为 EXIT,它要么退出循环,要么退出函数/过程(如果没有要退出的循环)。您可以添加一个 WHEN 来检查某些条件。

您可以将上面的示例重写如下:

DECLARE
   done  BOOLEAN;
BEGIN
    FOR i IN 1..50 LOOP
     EXIT WHEN done;
   END LOOP;
END;

如果您想从一些嵌套循环和逻辑的深处退出,这可能还不够,但比几个 GOTO 和 NULL 更清晰。

于 2008-10-07T10:23:55.070 回答
1

这并不完全是问题的答案,但值得注意的是:

continuePL/SQL 和所有其他以相同方式使用它的编程语言中的语句很容易被误解。

如果编程语言开发人员skip改为调用关键字,会更明智、更清晰、更简洁。

对我来说,有 C、C++、Python 的背景……一直很清楚“继续”是什么意思。

但是如果没有那个历史背景,你可能会结束对这段代码的解释

for i in .. tab_xy.count loop
    CONTINUE WHEN some_condition(tab_xy(i));
    do_process(tab_xy(i));
end loop;

像这样:

循环遍历表 tab_xy 的记录。

如果记录满足 some_condition 则继续,否则忽略此记录。

Do_process 记录。

这种解释是完全错误的,但是如果您将 PL/SQL 代码想象成一种烹饪收据并大声朗读,就会发生这种情况。

事实上,就在昨天,它发生在一位经验丰富的开发同事身上。

于 2019-09-26T12:36:51.537 回答