我想在 Oracle 存储过程中编写一段代码,在其中定义了一个显式游标,并且我想将其转换为通用的
SYS_REFCURSOR
。
我想避免基于显式游标的 SQL 定义任何特定的对象类型。
提前谢谢您。
代码应该是:
CREATE OR REPLACE procedure TransformExplicitCursor(out_sysrefcursor out sys_refcursor) AS
BEGIN
DECLARE
CURSOR lc_explicit_cursor IS SELECT ....-- here a complex select
-- todo something in order to obtain a sys_refcursor from lc_explicit_cursor
END TransformCursor;
引用游标可以使用变量打开 SQL 来提供 SQL 语句而不是字符串文字,因此您可以仅在一个地方定义 SQL 并在多个地方使用它:
declare
tmp_cursor sys_refcursor;
tmp_sql varchar2(32767) := 'select * from dual';
begin
if true
then
open tmp_cursor for tmp_sql;
else
open tmp_cursor for tmp_sql;
end if;
end;
如果您需要在多行上使用复杂的 SQL,其中包含大量单引号字符串,请使用替代引用语法
q'{...}'
,这样您就不必使用 SQL 转义这些单引号,并且还可以使用尽可能多的单引号。根据您需要的线路。您还可以通过绑定变量注入参数:
declare
var_dummy varchar(1);
tmp_cursor sys_refcursor;
tmp_sql varchar2(32767) := q'{
select :dummy1
from dual
where dummy = :dummy2
}';
begin
if true
then
open tmp_cursor for tmp_sql using 'A','X';
fetch tmp_cursor into var_dummy;
dbms_output.put_line(var_dummy);
else
open tmp_cursor for tmp_sql using 'B','X';
fetch tmp_cursor into var_dummy;
dbms_output.put_line(var_dummy);
end if;
end;
但是,如果您打算在过程中使用 SQL,则应该使用普通游标而不是引用游标。当使用代码不知道也不关心 SQL 是什么,只关心结果是什么(当然是一组特定的列)时,会使用引用游标,并且通常通过调用过程来使用,而不是在打开它们的过程相同。
因此,如果您在定义它们的过程中使用它,并且每次重用相同 SQL 时唯一的更改是参数,请使用 游标参数:
declare
var_dummy varchar(1);
CURSOR tmp_cursor (dummy1 IN varchar2,dummy2 IN varchar2)
IS
select dummy1
from dual
where dummy = dummy2;
begin
open tmp_cursor ('A','X');
fetch tmp_cursor into var_dummy;
dbms_output.put_line(var_dummy);
close tmp_cursor;
open tmp_cursor ('B','X');
fetch tmp_cursor into var_dummy;
dbms_output.put_line(var_dummy);
close tmp_cursor;
end;