У меня есть хранимая процедура, которая выбирает одно поле из одной строки (на основе условного оператора) и сохраняет его в локальной переменной. На основании значения этого поля я обновляю то же поле в той же строке таблицы (используя тот же условный оператор). Таким образом, процедура сначала делает выбор в локальной переменной, а затем обновляет то же поле в той же строке. Затем процедура возвращает набор результатов с помощью выбора переменной таблицы (я также пытался использовать временную таблицу). Набор результатов не содержит переменную или поле, которое я обновил. Он даже не содержит полей из этой таблицы.
Процедура работает правильно при вызове из Management Studio или из тестового приложения C #. Однако при вызове из моего приложения VB6 набор результатов не возвращается. Однако все обновления базы данных все еще выполняются.
Я попытался написать хранимую процедуру с транзакцией и без, с TRY ... CATCH и без, и обе одновременно. Я пробовал различные комбинации изоляции транзакций. Никаких исключений не выдается, и транзакция всегда будет зафиксирована. Я также использовал подсказку WITH (NOLOCK) в операторе select. Если я пропущу обновление таблицы, оно будет работать. Если я опускаю присваивание локальной переменной и вместо жесткого кода значение, это работает. Если я просто использую select, в который я помещу переменную, она НЕ будет работать.
Интересно, что если я добавлю в процедуру какой-нибудь случайный оператор выбора, он вернет этот набор результатов. Я даже могу выбрать это же поле из той же записи, которую я назначил моей переменной без проблем. Но он все равно не вернет желаемый набор результатов.
Мой результирующий набор представляет собой выбор из табличной переменной, которая заполняется с помощью операторов вставки с использованием переменных, установленных в течение всей процедуры. Нет никаких объединений таблиц вообще. Я передаю 2 параметра в процедуру, один из которых используется в моем условном выражении в исходном выборе. Но я все равно получаю то же поведение, когда опускаю и параметры, и значения жесткого кода.
Я попытался перезапустить свой SQL Server (2005 версия 9.0.4053), перезагрузить компьютер, я попытался с включенным и выключенным 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: Мы только что обнаружили, что если мы создадим произвольную таблицу для хранения данных, которые будут возвращены последним оператором выбора вместо использования табличной переменной, процедура работает ...