如何在存储过程Oracle PL/SQL中获取具有显式游标的SYS_REFCURSOR

问题描述 投票:0回答:1

我想在 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;
oracle stored-procedures sys-refcursor oracle-cursor
1个回答
0
投票

引用游标可以使用变量打开 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;
© www.soinside.com 2019 - 2024. All rights reserved.