У меня есть хранимая процедура, которая выбирает одно поле из одной строки (на основе условного оператора) и сохраняет его в локальной переменной. На основе значения этого поля я обновляю то же поле в той же строке таблицы (используя тот же условный оператор). Таким образом, процедура сначала выполняет выбор в локальной переменной, а затем обновляет то же поле той же строки. Затем процедура возвращает набор результатов с помощью выбора переменной таблицы (я также попытался использовать временную таблицу). Набор результатов не содержит обновленной переменной или поля. Он даже не включает поля из этой таблицы.
Процедура работает правильно при вызове либо из Management Studio, либо из тестового приложения C #. Однако при вызове из моего приложения VB6 набор результатов не возвращается. Однако все обновления базы данных по-прежнему выполняются.
Я пробовал писать хранимую процедуру с транзакцией и без, с TRY ... CATCH и без, и то и другое одновременно. Я пробовал различные комбинации изоляции транзакций. Никаких исключений не создается, и транзакция всегда фиксируется. Я также использовал подсказку WITH (NOLOCK) для оператора select. Если я опущу обновление таблицы, это сработает. Если я оставлю присвоение локальной переменной и вместо этого жестко запрограммирую значение, оно будет работать. Если я просто использую select, где я бы поместил переменную, это НЕ будет работать.
Интересно, что если я добавлю в процедуру какой-нибудь оператор случайного выбора, он вернет этот набор результатов. Я даже могу без проблем выбрать то же поле из той же записи, которую я назначаю своей переменной. Но он все равно не вернет желаемый результат.
Мой набор результатов - это выборка из табличной переменной, которая заполняется с помощью операторов вставки с использованием переменных, установленных на протяжении всей процедуры. Объединений таблиц нет вообще. Я передаю процедуре 2 параметра, один из которых используется в моем условном операторе в исходном выборе. Но я все равно получаю такое же поведение, когда опускаю как параметры, так и значения жесткого кода.
Я попытался перезапустить свой SQL Server (версия 9.0.4053 2005 года), перезапустить свой компьютер, я попытался включить и выключить NOCOUNT, у меня в основном нет идей.
Изменить - Подробная информация о вызове VB и подписи хранимой процедуры:
Я постараюсь дать как можно более подробное описание, не публикуя фактический код. На самом деле я отправляю это другому разработчику, который работает со мной, так что терпите меня.
Вызов VB6:
With cmdCommand
.ActiveConnection = cnnConn
.CommandType = adCmdStoredProc
.CommandText = "uspMyStoredProcedure"
.Parameters("@strParam1") = strFunctionParameter1
.Parameters("@bolParam2") = bolFunctionParameter2
.Execute
End With
MyResultSet.CursorLocation = adUseClient
MyResultSet.Open cmdCommand, , adOpenStatic, adLockReadOnly
Сигнатура хранимой процедуры:
CREATE PROCEDURE uspMyStoredProcedure
@strParam1 NVARCHAR(XX),
@bolParam2 BIT
AS
BEGIN
SET NO COUNT ON
DECLARE @var1 NVARCHAR(XX),
@var2 NVARCHAR(XX),
@var3 NVARCHAR(XX),
@var4 INT,
@var5 BIT
--DECLARATION OF OTHER VARIABLES
DECLARE @varTableVariable TABLE
(
strTblVar1 NVARCHAR(XX) ,
intTblVar2 INT ,
strTblVar3 NVARCHAR(XX) ,
bolTblVar4 BIT ,
datTblVar5 DATETIME
)
SELECT @var1 = t.Field1, @var2 = t.Field2
FROM Table1 t
WHERE t.ID = @strParam1
SELECT @var3 = t2.Field1
FROM Table2 t2
IF (Condition)
BEGIN
SET @var4 = 1
IF (Condition)
BEGIN
--SET SOME VARIABLES
END
ELSE
BEGIN
UPDATE TABLE1
SET Field3 = @var4
WHERE Field1 = @strParam1
END
END
ELSE
BEGIN
IF(Condition)
BEGIN
SELECT @var5 = ISNULL(Condition)
FROM Table3 t3
WHERE t3.Field = @strParam1
--SET SOME MORE VARIABLES
END
END
IF(Condition)
BEGIN
UPDATE Table1
SET Field5 = @SomeVariable
WHERE Field1 = @strParam1
END
INSERT INTO Table4 (Field1, Field2, Field3)
SELECT @SomeVar1, @someVar2, @SomeVar3
FROM SomeOtherTable
WHERE Field3 = @someVariable
IF(Condition)
BEGIN
INSERT INTO @varTableVariable (strTblVar1, intTblVar2,
strTblVar3, bolTblVar4, datTblVar5 )
VALUES (@SomeVar1, @SomeVar2, @SomeVar3, @SomeVar4, @SomeVar5)
END
SELECT *
FROM @varTableVariable
END
Итак, по сути, процедура принимает два параметра. Он выполняет ряд простых операций - вставку и выбор данных из пары разных таблиц, обновление таблицы и вставку строки в переменную таблицы.
Процедура завершается выбором переменной таблицы. Нет ничего особенного ни в самой процедуре, ни в звонке от VB6. Как указывалось ранее, наблюдаемое поведение необычно в том смысле, что при комментировании определенных разделов вызов и возврат будут работать - данные возвращаются. Вызов той же процедуры из тестового приложения C # .NET работает и успешно возвращает желаемый результат.
Все, что нам удается вернуть в приложение VB6, - это пустой набор записей.
Редактировать 2: мы только что обнаружили, что если мы создадим произвольную таблицу для хранения данных, которые должны быть возвращены последним оператором выбора, вместо использования табличной переменной, процедура будет работать ...