【发布时间】:2014-05-14 07:21:19
【问题描述】:
我正在将现有应用程序从 SQL Server 转换为 Oracle,但遇到了障碍。我正在尝试将匿名块作为动态 SQL 执行并返回结果集。然而,我尝试过的任何东西似乎都无法返回任何值。由于设计限制,存储过程已被淘汰。
我的查询定义为:
DECLARE type id_array IS TABLE OF number;
t_Ids id_array;
BEGIN
UPDATE CSM_RECORDS SET MIGRATION_STATE = 1, LAST_UPDATE = CURRENT_DATE
WHERE OBJECT_UID IN
(SELECT OBJECT_UID
FROM CSM_RECORDS obj
WHERE MIGRATION_STATE = 0
AND ROWNUM <= :BatchSize)
AND (:BatchName IS NULL OR obj.BATCH_NAME = :BatchName)
RETURNING OBJECT_UID BULK COLLECT INTO t_Ids;
OPEN rcursor FOR SELECT * FROM CSM_RECORDS;-- WHERE OBJECT_UID IN (t_Ids);
END;
你可以看到我已经注释掉了光标上的 WHERE 子句,试图让 anything 完全返回。
在 C# 方面,我有:
OracleCommand getNextNodesC = new OracleCommand(SQL_AS_SHOWN_ABOVE, conn);
getNextNodesC.BindByName = true;
OracleParameter batchSizeP = new OracleParameter("BatchSize", OracleDbType.Int32);
batchSizeP.Value = batchSize;
getNextNodesC.Parameters.Add(batchSizeP);
OracleParameter batchNameP = new OracleParameter("BatchName", OracleDbType.Varchar2);
batchNameP.Value = batchName;
getNextNodesC.Parameters.Add(batchNameP);
OracleParameter returnCursor = new OracleParameter("rcursor", OracleDbType.RefCursor);
returnCursor.Direction = ParameterDirection.Output;
getNextNodesC.Parameters.Add(returnCursor);
getNextNodesC.ExecuteNonQuery();
return ((Oracle.ManagedDataAccess.Types.OracleRefCursor)returnCursor.Value).GetDataReader();
最终目标是我可以使用的DbDataReader,但在上面的代码中,returnCursor.Value 似乎仍然为空。我尝试了Output 与ReturnValue 参数和ExecuteNonQuery() 和ExecuteReader() 的各种组合,但无济于事。
任何指针都将不胜感激,但实际上可以完成我正在寻找的代码示例将是壮观的。
【问题讨论】:
-
OPEN CURSOR之后的代码在哪里。OPEN Cursor只会设置光标并使其准备好从中读取,它不会将任何数据返回给调用者 -
那么我将如何将数据返回给调用者?很有可能是我的问题。我试过在
OPEN...行之后做一个RETURN rcursor;,但这似乎并没有改变任何东西。 -
尝试按位置绑定以将其从图片中删除,另请参阅 oracle 主页中 odp.net 示例目录中的参考光标示例代码。
-
..还大大简化了 sql,所以你可以保证一些行会回来(摆脱嵌套选择)
-
按位置绑定会导致
ORA-00932: inconsistent datatypes: expected - got CURSER错误。我不知道这是离解决方案更近了一步,还是离解决方案更近了一步。编辑:我实际上在游标语句中注释掉了整个 WHERE 子句(见上文),以保证我应该得到一些回报。
标签: c# sql oracle plsql odp.net