Oracle中的游标循环

10
请告诉我如何在Oracle中使用游标循环。
如果我使用以下代码,一切都正常。
for rec in (select id, name from students) loop
    -- do anything
end loop;

但是如果我为这个 SQL 语句定义变量,它就不能正常工作。

v_sql := 'select id, name from students';

for rec in v_sql loop
    -- do anything
end loop;

Error: PLS-00103

4个回答

13

为了解决您问题中的第二种方法所涉及的问题,您需要使用游标变量并显式地打开游标并获取数据。不允许在 FOR 循环中使用游标变量:

declare
  l_sql varchar2(123);        -- variable that contains a query
  l_c   sys_refcursor;        -- cursor variable(weak cursor). 
  l_res your_table%rowtype;   -- variable containing fetching data  
begin
  l_sql := 'select * from your_table';

  -- Open the cursor and fetching data explicitly 
  -- in the LOOP.

  open l_c for l_sql;

  loop
    fetch l_c into l_res;
    exit when l_c%notfound;   -- Exit the loop if there is nothing to fetch.

     -- process fetched data 
  end loop;

  close l_c; -- close the cursor
end;

了解更多


1
目前来看,这是最合适的答案。我本以为一切都会更容易。感谢您的决定。 - Anton Barycheuski

7

尝试这个:

cursor v_sql is
select id, name from students;

for rec in v_sql 
loop
    -- do anything
end loop;

如果不需要,就不必打开、提取或关闭光标。


我认为,如果我在定义阶段就知道 SQL 代码,那么这段代码将会运行成功,但实际上它是在执行阶段生成的。 - Anton Barycheuski
你可以在游标定义中定义参数,但只能用于where子句。如果需要动态设置表,则“OPEN c FOR string”可能是最好的选择。 - Nicolas Constant Brix

2
您没有在任何地方执行该 SQL 字符串。只需执行以下操作
v_sql := 'select id, name from students';
open cur for v_sql;
for rec in cur loop
    -- do anything
end loop;

或者你可以这样做

cursor cur is select id, name from students;
open cur;
for rec in cur loop
        -- do anything
end loop;

或者你也可以这样做。
for rec in (select id, name from students) loop
    -- do anything
end loop

0

如果您在运行时进行查询,则必须使用Refcursor。实际上,refcursors是指向查询的指针,它们不会占用检索到的行的任何空间。普通游标将无法正常工作。

declare 
v_sql varchar2(200);
rec sys_refcursor;
BEGIN
v_sql := 'select id, name from students';

open rec for v_sql 
loop
fetch
exit when....
-- do anything
end loop;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接