我有这张桌子:
ALLITEMS
---------------
ItemId | Areas
---------------
1 | EAST
2 | EAST
3 | SOUTH
4 | WEST
Run Code Online (Sandbox Code Playgroud)
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');
Run Code Online (Sandbox Code Playgroud)
在MSSQL中,要从动态SQL获取游标,我可以这样做:
DECLARE @v_sqlStatement VARCHAR(2000);
SET @v_Sqlstatement = 'SELECT * FROM ALLITEMS';
EXEC (@v_sqlStatement); --returns a resultset/cursor, just like calling SELECT
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)
但我得到的只是"匿名阻止完成".
如何让它返回光标?
(我知道如果我做AUTOPRINT,它会打印出REFCURSOR中的信息(它不是在上面的代码中打印,但这是另一个问题))
我将从代码(ODBC,C++)调用此动态SQL,我需要它来返回游标.
我该怎么做呢?我很难过.
Pet*_*ang 41
您可以编写一个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;
Run Code Online (Sandbox Code Playgroud)
这将返回光标.
确保尽可能不将SELECT
-String放在PL/SQL中的引号中.将它放在字符串中意味着它无法在编译时检查,并且必须在使用它时对其进行解析.
如果您确实需要使用动态SQL,可以将查询放在单引号中:
OPEN my_cursor FOR 'SELECT * FROM allitems';
Run Code Online (Sandbox Code Playgroud)
无论何时调用该函数,都必须解析此字符串,这通常会更慢并且在查询中隐藏错误直到运行时.
确保尽可能使用绑定变量以避免硬分析:
OPEN my_cursor FOR 'SELECT * FROM allitems WHERE id = :id' USING my_id;
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)