如何从执行动态SQL的Oracle PL/SQL匿名块返回结果集/游标?

我有这个表:

ALLITEMS
---------------
ItemId  | Areas
---------------
1       | EAST
2       | EAST
3       | SOUTH
4       | WEST

DDL:

drop table allitems;

Create Table Allitems(ItemId Int,areas Varchar2(20));
Insert Into Allitems(Itemid,Areas) Values(1,'east');
Insert Into Allitems(ItemId,areas) Values(2,'east');
insert into allitems(ItemId,areas) values(3,'south');
insert into allitems(ItemId,areas) values(4,'east');

在MSSQL中,要从动态SQL获取游标,我可以做:

DECLARE @v_sqlStatement VARCHAR(2000);
SET @v_Sqlstatement = 'SELECT * FROM ALLITEMS';
EXEC (@v_sqlStatement); --returns a resultset/cursor, just like calling SELECT 

在Oracle中,我需要使用PL / SQL块:

SET AUTOPRINT ON;
DECLARE
 V_Sqlstatement Varchar2(2000);
 outputData SYS_REFCURSOR;
BEGIN
 V_Sqlstatement := 'SELECT * FROM ALLITEMS';
 OPEN outputData for v_Sqlstatement; 
End;
--result is : anonymous block completed

但我所得到的只是“匿名块完成”。
如何让它返回光标?
(我知道如果我做AUTOPRINT,它将打印出REFCURSOR中的信息(它不是在上面的代码中打印,而是另一个问题))

我将从代码(ODBC,C)中调用此动态SQL,我需要它返回一个游标。
我该如何做?我被困了

最佳答案
您可以编写一个PL / SQL函数来返回该游标(或者您可以将该函数放在一个包中,如果您有更多的代码与此相关):

CREATE OR REPLACE FUNCTION get_allitems
  RETURN SYS_REFCURSOR
AS
  my_cursor SYS_REFCURSOR;
BEGIN
  OPEN my_cursor FOR SELECT * FROM allitems;
  RETURN my_cursor;
END get_allitems;

这将返回光标。

确保在可能的情况下不要将SELECT-String置于PL / SQL中的引号中。将其放入字符串意味着它无法在编译时检查,并且必须在使用它时进行解析。

如果您真的需要使用动态SQL,您可以将查询放在单引号中:

  OPEN my_cursor FOR 'SELECT * FROM allitems';

每当调用函数时,必须解析此字符串,这通常会较慢,并在查询中隐藏错误,直到运行时为止。

确保在可能的情况下使用绑定变量来避免hard parses

  OPEN my_cursor FOR 'SELECT * FROM allitems WHERE id = :id' USING my_id;

转载注明原文:如何从执行动态SQL的Oracle PL/SQL匿名块返回结果集/游标? - 代码日志