如何以及何时在Oracle中使用sys_refcursor


Answers:


10

游标是指向查询结果集的指针。通过返回a,sys_refcursor您可以允许客户端根据需要从查询中获取尽可能多的行。在有状态的应用程序中,可以使用它来翻页结果。

与编写返回数组的PL / SQL函数相比,游标可以提供更大的灵活性,因为它完全取决于客户端要提取多少行以及何时停止。就是说,我没有发现这种额外的灵活性很有用的情况。

值得注意的是,的sys_refcursor类型是弱类型,因此您可以返回指向查询的指针,这些查询不仅具有from或where子句不同,而且具有不同数量和类型的列。或者,您可以使用强类型的游标,其中结果集中的列是固定的。

这使您可以编写返回不同查询的函数,如下所示:

create function get_data ( type varchar2 ) return sys_refcursor as
  ret_cur sys_refcursor;
begin

  if type = 'EMP' then
    open ret_cur for select * from emp;
  elsif type = 'DEPT' then
    open ret_cur for select * from dept;
  end if;

  return ret_cur;
end;

但是,如果您要sys_refcursor像上面那样创建通用的“打开查询”功能,则可能是做错了!


@Chris ...您的示例函数为什么是“错误的”?
约翰尼·吴

2
@JohnnyWu的“给我任何东西”功能将更难以管理。在所有情况下,您如何进行测试以确保获得正确的结果?那么安全性呢?如果要构建框架,这可能是必需的。但是对于一般的商业逻辑,最好有单独get_empsget_depts功能
克里斯-撒克逊

1

作为一种可能性的例子:由于它后面是pl / sql,因此可以定义一个对象来代表一行,定义这些对象的pl / sql表,

create type T_MY_TABLE as table of t_my_object;

并以

OPEN p_recordset FOR select * from table( v_my_table );

因此,与其在数据库表上构造mongo(通常是密集和/或神秘的直接查询),不如创建一个内部表并拥有pl / sql的全部功能来填充它。收集结果集的客户端绝非明智之举。从管理角度来看,更改内部表的定义比更改数据库表更容易。

同样,当使用Jasper之类的报告生成器时,您可以将SQL从报告中推出并进入数据库,然后只需调用该过程即可获取记录集,而使报告侧专注于格式设置。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.