将基于 CTE 的游标传递给应用程序时,.NET Oracle SP 调用错误 ORA-00604 和 ORA-01001
SP如下: SP代码
调用它的C#代码:C# 代码(这是更新 #3 中描述的更改后的版本)
使用 System.Data.OracleClient、.NET 3.5 SP1、Oracle Express 11g,Windows 7 x64。
这在 SQL Developer(2,3) 中执行得很好。但是,当从 .NET 调用时,会发生这种情况:(请参阅更新 3)
更新 1: 当游标参数读取全局临时值时,使用带有 2 个 OUT 参数的 ExecuteReader 有效 。表与常规表连接。此外,这最终必须在只能使用 ExecuteReader 的 ORM (Lightspeed) 内工作。
更新 2: 看起来 SQL Developer 内部也发生了同样的事情。我用这个:
LOOP
FETCH results INTO v_rec;
EXIT WHEN results%notfound;
DBMS_OUTPUT.PUT_LINE(v_rec.name);
END LOOP;
...来获取“结果”的内容:在SP中工作,并在调用SP的PL/SQL块中使用时产生ORA-01001(当然,在删除SP内的相同代码之后) 。
更新3:将“results1”转换为OUT参数解决了SQL Developer中的问题,显然是游标在超出范围时自动关闭。但是,.NET 现在出现了问题:
ORA-00604: error occurred at recursive SQL level 1
ORA-01059: parse expected before a bind or execute
请参阅 C# 代码 了解参数。尝试了 ExecuteReader、ExecuteNonQuery 和 ExecuteOracleNonQuery 方法,但无济于事。
The SP is as follows: SP code
C# code calling it: C# code (this is the version after making changes described in update #3)
Using System.Data.OracleClient, .NET 3.5 SP1, Oracle Express 11g, Windows 7 x64.
This executes fine in SQL Developer(2,3). However, when calling from .NET, this happens: (see update 3)
Update 1: Using ExecuteReader with 2 OUT parameters works, when the cursor parameter is reading a global temp. table joined with a regular table. Also, this will eventually have to work inside an ORM (Lightspeed) which can only use ExecuteReader.
Update 2: Looks like same thing happens inside SQL Developer. I used this:
LOOP
FETCH results INTO v_rec;
EXIT WHEN results%notfound;
DBMS_OUTPUT.PUT_LINE(v_rec.name);
END LOOP;
... to fetch the contents of "results": works in the SP, and produces ORA-01001 when used in the PL/SQL block calling the SP (after removing the same code inside the SP, of course).
Update 3: Turning "results1" into an OUT parameter solved the problem in SQL Developer, which apparently was cursor being automatically closed when going out of scope. However, .NET now barfs:
ORA-00604: error occurred at recursive SQL level 1
ORA-01059: parse expected before a bind or execute
See C# code for parameters. Tried ExecuteReader, ExecuteNonQuery and ExecuteOracleNonQuery methods, to no avail.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不是
System.Data.OracleClient
类的专家,因为我通常使用 Oracle 的 ODP.NET。所以我只能给你一些提示:通常,当你有一个Oracle存储过程时,你会调用
ExecuteNonQuery
而不是ExecuteReader
,因为Oracle从不直接从存储过程返回结果集。存储过程。如果您有一个CURSOR
类型的OUT
参数,则使用ExecuteReader
可能会起作用。但你有两个。在任何情况下,应该有效的是调用
ExecuteNonQuery
,然后检索OUT
参数:PS
System.Data.OracleClient
类已被弃用。I'm not an expert on the
System.Data.OracleClient
classes since I usually use Oracle's ODP.NET. So I can only give you some hints:Typically, when you have an Oracle stored procedure., you call
ExecuteNonQuery
instead ofExecuteReader
since Oracle never directly returns a result set from a stored procedure. UsingExecuteReader
might work if you have a singleOUT
paramter of typeCURSOR
. But you have two of them.What should work in any case, is to call
ExecuteNonQuery
and then retrieve theOUT
parameters:P.S. The
System.Data.OracleClient
classes are deprected.