如何从执行动态 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,并且我需要它返回游标如何?
I have this table:
ALLITEMS
---------------
ItemId | Areas
---------------
1 | EAST
2 | EAST
3 | SOUTH
4 | WEST
The 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');
In MSSQL, to get a cursor from a dynamic SQL I can do:
DECLARE @v_sqlStatement VARCHAR(2000);
SET @v_Sqlstatement = 'SELECT * FROM ALLITEMS';
EXEC (@v_sqlStatement); --returns a resultset/cursor, just like calling SELECT
In Oracle, I need to use a PL/SQL Block:
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
**But all I get is
anonymous block completed".
How do I get it to return the cursor?
(I know that if I do AUTOPRINT, it will print out the information in the REFCURSOR (it's not printing in the code above, but thats another problem))
I will be calling this Dynamic SQL from code (ODBC,C++), and I need it to return a cursor. How?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以编写一个 PL/SQL 函数来返回该游标(或者,如果您有更多与此相关的代码,则可以将该函数放入一个包中):
这将返回游标。
确保尽可能不要将
SELECT
-String 放入 PL/SQL 中的引号中。将其放入字符串中意味着无法在编译时对其进行检查,并且每次使用时都必须对其进行解析。如果您确实需要使用动态 SQL,您可以将查询放在单引号中:
每当调用函数时都必须解析该字符串,这通常会比较慢,并且会在运行时隐藏查询中的错误。
确保尽可能使用绑定变量,以避免 硬解析:
You can write a PL/SQL function to return that cursor (or you could put that function in a package if you have more code related to this):
This will return the cursor.
Make sure not to put your
SELECT
-String into quotes in PL/SQL when possible. Putting it in strings means that it can not be checked at compile time, and that it has to be parsed whenever you use it.If you really need to use dynamic SQL you can put your query in single quotes:
This string has to be parsed whenever the function is called, which will usually be slower and hides errors in your query until runtime.
Make sure to use bind-variables where possible to avoid hard parses:
在 SQL*Plus 中,您还可以使用
REFCURSOR
变量:in SQL*Plus you could also use a
REFCURSOR
variable:您应该能够将游标声明为绑定变量(在其他 DBMS 中称为参数),
就像 Vincent 所写的那样,您可以执行以下操作:
您必须将 3 个变量绑定到该脚本。 “someField”的输入字符串、“someFilterValue”的值和“yourCursor”的游标(必须声明为输出变量)。
不幸的是,我不知道如何从 C++ 中做到这一点。 (不过,有人可以说对我来说是幸运的。;-))
根据您使用的访问库,这可能是一种巨大的痛苦,也可能是直接的。
You should be able to declare a cursor to be a bind variable (called parameters in other DBMS')
like Vincent wrote, you can do something like this:
You'd have to bind 3 vars to that script. An input string for "someField", a value for "someFilterValue" and an cursor for "yourCursor" which has to be declared as output var.
Unfortunately, I have no idea how you'd do that from C++. (One could say fortunately for me, though. ;-) )
Depending on which access library you use, it might be a royal pain or straight forward.
需要设置此设置:
This setting needs to be set: