Сбой SQL-запроса Oracle только в одном процессе: «ORA-01405: извлечено значение столбца NULL» - PullRequest
3 голосов
/ 11 октября 2011

Я пытаюсь вызвать системную хранимую процедуру в "плагине", который я построил. Когда я тестирую свой плагин в тестовом приложении, он работает нормально. Когда я запускаю плагин в целевом приложении, для которого я его создаю, я получаю исключение от 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, но с отличным результатом от сервера базы данных. Что здесь может происходить?

Ответы [ 2 ]

2 голосов
/ 11 октября 2011

Эта ошибка возникает из-за старого кода OCI и предварительно скомпилированного кода, где требовалось установить переменную-индикатор для указания нулевого возврата для поля. Если переменная индикатора не объявлена, эта ошибка срабатывает, если встречается нулевое значение. Очевидно, что какой-то старый код все еще находится под вашими вызовами.

Другими словами, это проблема с данными. Я не знаю, с чего начать смотреть не по себе.

0 голосов
/ 11 октября 2011

Оказывается, мое целевое приложение выполняло мой код плагина, находясь в распределенной транзакции 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 выполняется вне внешней транзакции.

...