Почему я получаю противоречивые результаты при включенном условном наборе NOCOUNT в хранимой процедуре, вызываемой WebSphere Message Broker?

#sql-server #stored-procedures #messagebroker

#sql-server #хранимые процедуры #messagebroker

Вопрос:

Я пишу некоторые потоки для IBM WebSphere Message Broker, которые вызывают хранимые процедуры в удаленной базе данных Microsoft SQL Server. Моя проблема в том, что я иногда получаю результирующий набор, который должен быть возвращен, а иногда ничего не получаю.

Строки в хранимой процедуре, которые, по-видимому, вызывают проблему, являются:

 IF (@noCountInd > 0)
    SET NOCOUNT ON;
  

Когда я вызываю хранимую процедуру из узла базы данных в Message Broker, она возвращает результирующий набор при первом вызове, а при последующих вызовах ничего. Если SET NOCOUNT ON является безусловным, это срабатывает каждый раз. Это работает каждый раз, даже при выполнении вышеуказанного условия, если вызывается через командную строку SQL Server Management Studio.

Также кажется, что, когда между вызовами пройдет достаточно времени, чтобы Message Broker закрыл свое соединение с базой данных, тогда следующий вызов с новым подключением будет успешным.

Вот мой сокращенный код для создания этой проблемы:

Хранимая процедура

 CREATE PROCEDURE dbo.pTestConditionalNoCount
    @noCountInd bit = 0
AS

IF (@noCountInd > 0)
    SET NOCOUNT ON;

SELECT 'Success' AS RESULT;

RETURN 0;
  

ESQL в узле базы данных

 CREATE DATABASE MODULE testConditionalNoCount
    CREATE FUNCTION Main() RETURNS BOOLEAN
    BEGIN
        CALL pTestConditionalNoCount(TRUE,
            Environment.Variables.testConditionalNoCount.Results.Row[])
            IN Database.{'DATABASE_NAME'}.{'dbo'};      
        RETURN TRUE;
    END;

END MODULE;

CREATE PROCEDURE pTestConditionalNoCount(IN testNoCountInd BOOLEAN)
    LANGUAGE DATABASE
    DYNAMIC RESULT SETS 1
    EXTERNAL NAME pTestConditionalNoCount;
  

Вывод из узла трассировки

 Environment: ( ['MQROOT' : 0x29692478]
  (0x01000000:Name):Variables = (
    (0x01000000:Name):testConditionalNoCount = (
      (0x01000000:Name):Results = (
        (0x01000000:Name):Row = (
          (0x03000000:NameValue):RESULT = 'Success' (CHARACTER)
        )
      )
    )
  )
)
Environment: ( ['MQROOT' : 0x29692478]
  (0x01000000:Name):Variables = (
    (0x01000000:Name):testConditionalNoCount = (
      (0x01000000:Name):Results = 
    )
  )
)
Environment: ( ['MQROOT' : 0x29692478]
  (0x01000000:Name):Variables = (
    (0x01000000:Name):testConditionalNoCount = (
      (0x01000000:Name):Results = 
    )
  )
)
  

Версия SQL Server — Microsoft SQL Server 2005 — 9.00.5324.00 (X64), а Message broker — IBM WebSphere Message Broker 8.0.0.2.

У кого-нибудь есть идеи, что здесь происходит?

Обновить

Я запустил трассировку ODBC, и она показывает, что в случае сбоя возвращаются два набора результатов. Первое пустое, а второе — это ожидаемый мной результирующий набор.

Кажется, нет никакой разницы в способе вызова процедуры. Для каждого вызова регистрируется SQLExecute, затем SQLNumResultCols, который возвращает 1, если это сработало, и 0, если это не сработало.

Комментарии:

1. Включение параметра NOCOUNT подходит только для срока службы хранимой процедуры. Настройка возвращается к исходной настройке сеанса после завершения хранимой процедуры. Я подозреваю, что проблема в том, как сообщения о количестве строк начинают (неправильно) обрабатываться на уровне приложения или API, но я ничего не знаю о WebSphere Message Broker.

Ответ №1:

Я подозреваю, что это связано с кэшированием объектов хранимой процедуры, поэтому, когда вы отключаете соединение в режиме ожидания, вы видите, что вызов снова работает.

Возможно, стоит изучить трассировку ODBC двух последующих вызовов и посмотреть, есть ли какая-либо разница между двумя исполнениями (кроме, конечно, отсутствия результатов).