使用 'open cursor' 作为 'execute immediate'

Using 'open cursor' as 'execute immediate'

我正在尝试使用打开游标代替立即执行,因为我的 SQL 语句可以 return 多条记录。

 open cur1 for rule_sql;
   loop        
    dbms_output.put_line(cur1.rule_id);
   end loop;
 close cur1;

它抛出一条错误消息:"PLS-00487: Invalid reference to variable 'CUR1'"

有没有人遇到过类似的问题?非常感谢任何帮助:)

游标只是一个指向结果集的指针。要引用其内容,您需要将其 fetch 放入变量中。请注意,该变量必须是与查询投影相匹配的记录类型。如果您使用动态 SQL 来实现一组流动的列,这可能很难。

无论如何,像这样:

declare
    cur1 sys_refcursor;
   Type cur_rec is record (
        rule_id number,
        rule_desc varchar2(32));

    row1 cur_rec;
    ....
Begin
     ...
     open cur1 for stmt;
     for row1 in cur1 loop
           Dbms_output.put_line(row1.rule_id);
    End loop;
    ....
End;

"If I do not know the type of columns in the result then I cannot create a variable to capture the cursor values."

如果您不知道编译时查询的投影,事情就会变得更加复杂。您不能再使用 Native Dynamic SQL,您需要使用完整的 DBMS_SQL。

在 11g 中,Oracle 引入了所谓的方法 4 动态 SQL。这使我们能够以更多代码为代价来处理变量投影。 Adrian Billington 在他的 Oracle-developer.net 站点上对此进行了出色的介绍。 Check it out

您错过了 fetch 声明 - 请参阅 Example 7.4 in docs

open cur1 for rule_sql;
loop        
  fetch cur1 into my_row_variable;
  exit when cur1%notfound;
  dbms_output.put_line(cur1.rule_id);
end loop;
close cur1;