可以从执行立即语句中退出PL-SQL循环吗?



我有以下代码片段(简化以排除无关的细节):

<<cursor_loop>> 
LOOP 
  fetch c1 into somerecord;
  EXECUTE IMMEDIATE 'begin EXIT cursor_loop WHEN 1 = 1; end;';
END LOOP cursor_loop;

当我运行这个时,它失败了,出现了一个PLS-00201: identifier 'CURSOR_LOOP' must be declared错误。

如果我把循环标签放在execute immediate之外,我得到PLS-00376: illegal EXIT/CONTINUE statement; it must appear inside a loop

显然后者是错误的,但不清楚为什么前者是错误的。

可以在execute-immediate内的语句中退出这个循环吗?

由于作用域的关系,您不能在动态SQL中直接引用cursor_loop,正如其他人已经说过的那样。如果你坚持这种模式,那么你可以使用绑定变量标志将状态信息从动态代码传递回静态代码;比如:

DECLARE
  break_loop pls_integer;
...
  break_loop := 0;
  <<cursor_loop>> 
  LOOP 
    fetch c1 into somerecord;
    EXECUTE IMMEDIATE 'begin if 1 = 1 then :break_loop := 1; end if; end;'
      USING OUT break_loop;
    EXIT cursor_loop WHEN break_loop = 1;
  END LOOP cursor_loop;
...

稍微完整一点,但显然还是很做作,例如:

DECLARE
  break_loop pls_integer;
  somevar number;
  c1 sys_refcursor;
BEGIN
  OPEN c1 FOR
    select 1 from dual
    union all select 2 from dual
    union all select 3 from dual;
  break_loop := 0;
  dbms_output.put_line('before loop, break_loop is ' || break_loop);
  <<cursor_loop>> 
  LOOP 
    fetch c1 into somevar;
    exit when c1%notfound;
    dbms_output.put_line('got ' || somevar);
    EXECUTE IMMEDIATE 'begin if :somevar = 2 then :break_loop := 1; end if; end;'
      USING somevar, OUT break_loop;
    EXIT cursor_loop WHEN break_loop = 1;
  END LOOP cursor_loop;
  dbms_output.put_line('after loop, break_loop is ' || break_loop);
END;
/
PL/SQL procedure successfully completed.
before loop, break_loop is 0
got 1
got 2
after loop, break_loop is 1

在获取值'3'之前,因为动态检查而退出循环。

不行。

动态SQL语句在单独的作用域中运行——它不能引用调用块中定义的变量或操作它们的值(当然,除非您的动态语句具有绑定变量,允许您显式地创建两者之间的接口,并使用EXECUTE IMMEDIATEUSINGINTO子句来传递和返回值)。类似地,它不能引用循环名称,因为在执行动态语句时,该名称不在作用域中。

在这种情况下,不清楚为什么首先要使用EXECUTE IMMEDIATE而不是将EXIT编码为循环的正常部分。

我不这么认为。EXECUTE IMMEDIATE用于运行SQL语句,而不是任意块。来自文档:

EXECUTE IMMEDIATE语句构建并执行动态SQL
语句在单个操作中。它是一种手段,使当地人动态SQL处理大多数动态SQL语句。

https://docs.oracle.com/cd/B28359_01/appdev.111/b28370/executeimmediate_statement.htm

相关内容

  • 没有找到相关文章

最新更新