如何从 Oracle 函数返回 RefCursor?
我正在尝试执行用户定义的 Oracle 函数,该函数使用 ODP.NET 返回 RefCursor。这是该函数:
CREATE OR REPLACE FUNCTION PKG.FUNC_TEST (ID IN TABLE.ID%type)
RETURN SYS_REFCURSOR
AS
REF_TEST SYS_REFCURSOR;
BEGIN
OPEN REF_TEST FOR
SELECT *
FROM TABLE;
RETURN REF_TEST;
END;
/
我可以在 Toad 中调用该函数(从 Dual 中选择 func_test(7))并返回一个 CURSOR。但我需要使用 C# 和 ODP.NET 获取光标来填充数据集,但我不断收到 NullReferenceException - “对象引用未设置到对象的实例”。这就是我所拥有的:
OracleConnection oracleCon = new OracleConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);
OracleCommand sqlCom = new OracleCommand("select func_test(7) from dual", oracleCon);
sqlCom.Parameters.Add("REF_TEST", OracleDbType.RefCursor, ParameterDirection.ReturnValue);
OracleDataAdapter dataAdapter = new OracleDataAdapter();
dataAdapter.SelectCommand = sqlCom;
DataSet dataSet = new DataSet();
dataAdapter.Fill(dataSet); //FAILS HERE with NullReferenceException
我能够找到大量有关使用存储过程和 ODP.NET 的信息和示例,但对于从函数返回 RefCursors 的信息和示例却没有那么多。
编辑: 我不想向 OracleCommand 对象显式添加输入参数(即 sqlCom.Parameters.Add("id", OracleDbType.Int32,ParameterDirection.Input).Value = 7; ),因为这使得将其实现为通用 RESTful Web 服务变得困难,但我将其保留为最后的手段,但会使用存储过程。
非常感谢任何帮助!
I am trying to execute a user-defined Oracle function that returns a RefCursor using ODP.NET. Here is the function:
CREATE OR REPLACE FUNCTION PKG.FUNC_TEST (ID IN TABLE.ID%type)
RETURN SYS_REFCURSOR
AS
REF_TEST SYS_REFCURSOR;
BEGIN
OPEN REF_TEST FOR
SELECT *
FROM TABLE;
RETURN REF_TEST;
END;
/
I can call this function in Toad (select func_test(7) from dual) and get back a CURSOR. But I need to get the cursor using C# and ODP.NET to fill a DataSet, but I keep getting a NullReferenceException - "Object reference not set to an instance of an object". Here is what I have for that:
OracleConnection oracleCon = new OracleConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString);
OracleCommand sqlCom = new OracleCommand("select func_test(7) from dual", oracleCon);
sqlCom.Parameters.Add("REF_TEST", OracleDbType.RefCursor, ParameterDirection.ReturnValue);
OracleDataAdapter dataAdapter = new OracleDataAdapter();
dataAdapter.SelectCommand = sqlCom;
DataSet dataSet = new DataSet();
dataAdapter.Fill(dataSet); //FAILS HERE with NullReferenceException
I was able to find lots of info and samples on using stored procedures and ODP.NET, but not so much for returning RefCursors from functions.
EDIT: I do not want to explicitly add input parameters to the OracleCommand object (i.e. sqlCom.Parameters.Add("id", OracleDbType.Int32,ParameterDirection.Input).Value = 7;
) as that makes it difficult to implement this as a generic RESTful web service, but I'm reserving it as my last resort but would use stored procedures instead.
Any help is much appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您还缺少 sqlCom.ExecuteNonQuery();
,而不是从 Dual; 运行 select func_test(7); 让我们切换它来运行该函数并传入 该参数
基于可以在 @%ora_home%\Client_1\ODP.NET\samples\RefCursor\Sample5.csproj 找到的示例 ODP
如果您想避免(无论是好是坏!)每个自定义构建的参数集合proc/函数调用,您可以通过在代码中使用匿名块来解决这个问题,我修改了(再次未经测试!)上面的代码以反映这种技术。
这是一个很好的博客(来自 Mark Williams)展示了这种技术。
http://oradim.blogspot.com/2007/ 04/odpnet-tip-anonymous-plsql-and.html
I think you are missing the sqlCom.ExecuteNonQuery();
also, instead of running the select func_test(7) from dual; lets switch it to run the function and pass in the param
this is based on the example ODP that can be found @ %ora_home%\Client_1\ODP.NET\samples\RefCursor\Sample5.csproj
If you want to avoid (for better or worst!) the custom built param collection for each proc/function call you can get around that by utilizing anonymous blocks in your code, I have ammended (once again untested!) the code above to reflect this technique.
Here is a nice blog (from none other than Mark Williams) showing this technique.
http://oradim.blogspot.com/2007/04/odpnet-tip-anonymous-plsql-and.html