在C#代码中,我正在尝试从Oracle函数加载数据表。该函数具有SYS_REFCURSOR
返回类型。这是我尝试使用以下函数填充DataTable dt
的代码:
using (var connection = new OracleConnection(connstring))
{
connection.Open();
using (var command = new OracleCommand())
{
command.Connection = connection;
command.CommandText = "FNC_AXA_APPTS";
command.CommandType = CommandType.StoredProcedure;
OracleParameter retVal = new OracleParameter("PRS", OracleDbType.RefCursor);
retVal.Direction = ParameterDirection.ReturnValue;
command.Parameters.Add(retVal);
command.Parameters.Add(new OracleParameter("EG_PARAM", OracleDbType.Varchar2, 50)).Value = paramValue;
command.ExecuteNonQuery();
using (OracleDataReader reader = ((OracleRefCursor)command.Parameters["PRS"].Value).GetDataReader())
{
dt.Load(reader);
}
}
}
在某些情况下,Oracle 函数使用 dblink 到 SQL 数据库。在这些情况下,我会遇到以下异常...
ORA-01002: fetch out of sequence
ORA-02063: preceding line from GATE_LINK
。其中GATE_LINK
是数据库链接。到目前为止,我的研究证实,问题必须出在dblink上。
我们正在使用 Oracle Data Provider for .NET - 是否有可能不支持 dblink to SQL Server?或者如果是这样,我可以在 SQL 端配置什么来解决此问题?
我应该提到,我们通过VPN连接到Oracle DB,连接字符串使用以下格式:
"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST={0})(PORT={1}))(CONNECT_DATA=(SERVICE_NAME={2})));User Id={3};Password={4};"
提前感谢...
花了一天多的时间对此进行调查,我在发布问题后仅 10 分钟就被引导到答案。典型!
答案是在这里找到的 - https://community.oracle.com/thread/659625 - 所需要的只是将调用代码包装在事务中。工作代码如下所示:
using (var connection = new OracleConnection(connstring))
{
connection.Open();
using (var command = connection.CreateCommand())
{
// Start a local transaction
using (var transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted))
{
// Assign transaction object for a pending local transaction
command.Transaction = transaction;
command.CommandText = "FNC_AXA_APPTS";
command.CommandType = CommandType.StoredProcedure;
OracleParameter retVal = new OracleParameter("PRS", OracleDbType.RefCursor);
retVal.Direction = ParameterDirection.ReturnValue;
command.Parameters.Add(retVal);
command.Parameters.Add(new OracleParameter("EG_PARAM", OracleDbType.Varchar2, 50)).Value = paramValue;
command.ExecuteNonQuery();
using (OracleDataReader reader = ((OracleRefCursor)command.Parameters["PRS"].Value).GetDataReader())
{
dt.Load(reader);
}
}
}
}
我对解决方案的有限理解是,如果没有这个,事务将在 SQL Server 端提交,这会导致返回的游标在传递给 .NET 代码后在其迭代中失败。如果有人有更好的解释,请补充这个问题。
有价值的解决方案使用 (VaR 事务 = 连接。BeginTransaction(IsolationLevel.ReadCommitted)) {...我现在可以做到了,这么多tks