繁体   English   中英

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

[英]How to return a resultset / cursor from a Oracle PL/SQL anonymous block that executes Dynamic 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';

无论何时调用该函数,都必须解析此字符串,这通常会更慢并且在查询中隐藏错误直到运行时。

确保尽可能使用绑定变量以避免硬分析

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

在SQL * Plus中,您还可以使用REFCURSOR变量:

SQL> VARIABLE x REFCURSOR
SQL> DECLARE
  2   V_Sqlstatement Varchar2(2000);
  3  BEGIN
  4   V_Sqlstatement := 'SELECT * FROM DUAL';
  5   OPEN :x for v_Sqlstatement;
  6  End;
  7  /

ProcÚdure PL/SQL terminÚe avec succÞs.

SQL> print x;

D
-
X

您应该能够将游标声明为绑定变量(在其他DBMS中称为参数)

像文森特写的那样,你可以这样做:

begin
  open :yourCursor
    for 'SELECT "'|| :someField ||'" from yourTable where x = :y'
      using :someFilterValue;
end;

你必须将3个变量绑定到该脚本。 “someField”的输入字符串,“someFilterValue”的值和“yourCursor”的游标,必须声明为输出var。

不幸的是,我不知道你是如何用C ++做的。 (不过,我可以说幸运的是。;-))

根据您使用的访问库,它可能是一种皇家的痛苦或直接的。

需要设置此设置:

SET SERVEROUTPUT ON 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM