Oracle SQL 查询仅在一个进程中失败:“ORA-01405:获取的列值为 NULL”

发布于 2024-12-09 04:13:23 字数 1360 浏览 3 评论 0原文

我试图在我构建的“插件”中调用系统存储过程。当我在测试应用程序中测试我的插件时,它工作正常。当我在正在构建的目标应用程序中运行该插件时,我从 Oracle 得到了一个没有任何意义的异常。

我使用的是 Oracle 服务器 11.2.0.1.0 和 ODP.NET 2.112.2.0。

这是我的测试应用程序中来自 ODP.NET 的调试跟踪:

(ENTRY) OracleConnection::OracleConnection(1)
(POOL)  New connection pool created for: "Data Source=orcl;User ID=scott;"
(ENTRY) OracleConnection::CreateCommand()
OpsSqlPrepare2():SQL: begin DBMS_AQADM.START_QUEUE(queue_name => 'MyQueue'); end;
(EXIT)  OpsSqlExecuteNonQuery(): RetCode=0 Line=877
(EXIT)  OracleCommand::ExecuteNonQuery()
(ENTRY) OracleConnection::Dispose()
(ENTRY) OracleConnection::Close()

这是来自目标应用程序中运行的相同代码的 ODP.NET 调试跟踪:

(ENTRY) OracleConnection::OracleConnection(1)
(POOL)  New connection pool created for: "Data Source=orcl;User ID=scott;"
(ENTRY) OracleConnection::CreateCommand()
OpsSqlPrepare2():SQL: begin DBMS_AQADM.START_QUEUE(queue_name => 'MyQueue'); end;
(EXIT)  OpsSqlExecuteNonQuery(): RetCode=0 Line=877
(EXIT)  OracleCommand::ExecuteNonQuery()
(ENTRY) OpsErrGetOpoCtx()
(ERROR) Oracle error code=1405; ORA-01405: fetched column value is NULL
(EXIT)  OpsErrGetOpoCtx(): RetCode=0 Line=137
(ENTRY) OracleConnection::Dispose()
(ENTRY) OracleConnection::Close()

我不知道测试/目标应用程序之间可能有什么不同。这两个进程都作为本地管理员组的成员运行。两者都使用相同的连接字符串。两者都运行相同的 .NET 代码,但数据库服务器的结果不同。这里可能发生了什么?

I'm trying to call a system stored procedure in a "plugin" that I've built. When I test my plugin out in a test application, it works fine. When I run the plugin in the targeted app I'm building it for, I get an exception from Oracle that doesn't make any sense.

I'm using Oracle server 11.2.0.1.0, and ODP.NET 2.112.2.0.

Here's the debug trace from ODP.NET from my test app:

(ENTRY) OracleConnection::OracleConnection(1)
(POOL)  New connection pool created for: "Data Source=orcl;User ID=scott;"
(ENTRY) OracleConnection::CreateCommand()
OpsSqlPrepare2():SQL: begin DBMS_AQADM.START_QUEUE(queue_name => 'MyQueue'); end;
(EXIT)  OpsSqlExecuteNonQuery(): RetCode=0 Line=877
(EXIT)  OracleCommand::ExecuteNonQuery()
(ENTRY) OracleConnection::Dispose()
(ENTRY) OracleConnection::Close()

And here's debug trace from ODP.NET from the same code running in the targeted app:

(ENTRY) OracleConnection::OracleConnection(1)
(POOL)  New connection pool created for: "Data Source=orcl;User ID=scott;"
(ENTRY) OracleConnection::CreateCommand()
OpsSqlPrepare2():SQL: begin DBMS_AQADM.START_QUEUE(queue_name => 'MyQueue'); end;
(EXIT)  OpsSqlExecuteNonQuery(): RetCode=0 Line=877
(EXIT)  OracleCommand::ExecuteNonQuery()
(ENTRY) OpsErrGetOpoCtx()
(ERROR) Oracle error code=1405; ORA-01405: fetched column value is NULL
(EXIT)  OpsErrGetOpoCtx(): RetCode=0 Line=137
(ENTRY) OracleConnection::Dispose()
(ENTRY) OracleConnection::Close()

I'm at a loss as to what could be different between the test/target applications. Both processes are running as members of the local Administrators group. Both are using the same connection string. Both are running the same .NET code, but with a different outcome from the database server. What could be going on here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

避讳 2024-12-16 04:13:23

此错误来自旧的 OCI & prec 编译的代码,其中需要设置指示符变量来指示字段返回 null。当没有声明指示变量时,如果遇到空值,则会触发此错误。显然,一些较旧的代码仍然位于您所做的调用之下。

换句话说,这是一个数据问题。我不知道从哪里开始随意寻找。

This error comes from old OCI & prec-compiled code where an indicator variable was required to be set to indicate a null return for the field. When there is no indicator variable declared, this error is triggered if a null value is encountered. Obviously, some older code is still layered under the calls you made.

In other words, it is a data issue. I don't know where to start looking offhand.

神经大条 2024-12-16 04:13:23

事实证明,我的目标应用程序正在分布式 XA 事务(在我的例子中为 MSDTC)中执行我的插件代码。对DBMS_AQADM.START_QUEUE 的调用有一个我不知道的隐式COMMIT;。在这种情况下,错误消息显然没有任何帮助。

解决方案是将我的调用包装在以下内容中:

using (var scope = new TransactionScope(TransactionScopeOption.Surpress))
{
    // execute DBMS_AQADM.START_QUEUE code here
    scope.Complete();
}

这会导致对 DBMS_AQADM.START_QUEUE 的调用在环境事务之外运行。

It turns out that my target application was executing my plugin code while in Distributed XA Transaction (MSDTC in my case). The call to DBMS_AQADM.START_QUEUE has an implicit COMMIT; that I wasn't aware of. The error message is obviously not helpful at all in this case.

The solution is to wrap my call in in the following:

using (var scope = new TransactionScope(TransactionScopeOption.Surpress))
{
    // execute DBMS_AQADM.START_QUEUE code here
    scope.Complete();
}

This causes the call to DBMS_AQADM.START_QUEUE to run outside of the ambient transaction.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文