Команда VB6 ADO для SQL Server

Я получаю необъяснимую ошибку при запуске команды ADO в VB6 для базы данных SQL Server 2005.

Вот код, демонстрирующий проблему:

Sub ADOCommand()
   Dim Conn As ADODB.Connection
   Dim Rs As ADODB.Recordset
   Dim Cmd As ADODB.Command

   Dim ErrorAlertID As Long
   Dim ErrorTime As Date

   Set Conn = New ADODB.Connection
   Conn.ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Initial Catalog=database;Data Source=server"
   Conn.CursorLocation = adUseClient
   Conn.Open

   Set Rs = New ADODB.Recordset
   Rs.CursorType = adOpenStatic
   Rs.LockType = adLockReadOnly

   Set Cmd = New ADODB.Command
   With Cmd
      .Prepared = False
      .CommandText = "ErrorAlertCollect"
      .CommandType = adCmdStoredProc
      .NamedParameters = True
      .Parameters.Append .CreateParameter("@ErrorAlertID", adInteger, adParamOutput)
      .Parameters.Append .CreateParameter("@CreateTime", adDate, adParamOutput)
      Set .ActiveConnection = Conn
      Rs.Open Cmd

      ErrorAlertID = .Parameters("@ErrorAlertID").Value
      ErrorTime = .Parameters("@CreateTime").Value
   End With
   Debug.Print Rs.State ''// Shows 0 - Closed
   Debug.Print Rs.RecordCount ''// Of course this fails since the recordset is closed
End Sub

Итак, этот код работал не так давно, но теперь он не работает в последней строке с ошибкой:

Run-time error '3704': Operation is not allowed when the object is closed

Почему закрыто? Я только что открыл его, и СП возвращает строки.

Я выполнил трассировку, и вот что библиотека ADO фактически отправляет на сервер:

declare @p1 int
set @p1=1
declare @p2 datetime
set @p2=''2010-04-22 15:31:07:770''
exec ErrorAlertCollect @ErrorAlertID=@p1 output,@CreateTime=@p2 output
select @p1, @p2

Выполнение этого как отдельного пакета из моего редактора запросов дает:

Msg 102, Level 15, State 1, Line 4
Incorrect syntax near '2010'.

Конечно есть ошибка. Посмотрите на двойные одинарные кавычки там. Что, черт возьми, могло быть причиной этого? Я пробовал использовать adDBDate и adDBTime в качестве типов данных для параметра даты, и они дали те же результаты.

Когда я задаю параметры adParamInputOutput, я получаю следующее:

declare @p1 int
set @p1=default
declare @p2 datetime
set @p2=default
exec ErrorAlertCollect @ErrorAlertID=@p1 output,@CreateTime=@p2 output
select @p1, @p2

Запуск этого как отдельной партии дает:

Msg 156, Level 15, State 1, Line 2
Incorrect syntax near the keyword 'default'.
Msg 156, Level 15, State 1, Line 4
Incorrect syntax near the keyword 'default'.

Какого черта? SQL Server не поддерживает такой синтаксис. Вы можете использовать только ключевое слово DEFAULT в фактическом операторе выполнения SP.

Я должен отметить, что удаление лишних одинарных кавычек из приведенного выше оператора приводит к нормальной работе SP.

... Боже мой. Я только что разобрался. Думаю, это все равно стоит опубликовать.


person ErikE    schedule 22.04.2010    source источник
comment
''datetime'' - это просто известная ошибка в профилировщике (я думаю, исправлена ​​в SP2)   -  person Alex K.    schedule 23.04.2010
comment
Спасибо. Странно, что профилировщик сообщил о чем-то отличном от настоящего. Проверю уровень Service Pack сервера.   -  person ErikE    schedule 24.04.2010


Ответы (2)


Ответ заключается в том, что хранимой процедуре требуется SET NOCOUNT ON наверху, поскольку ADO останавливается в момент получения ответа «Затронутые строки», а хранимая процедура имеет оператор обновления перед окончательным выбором.

Я понятия не имею, почему трассировка показывает синтаксис ADODB, который не работает правильно при отправке самостоятельно, но очевидно, что библиотека ADODB НЕ получает ошибку при своих запросах. Вся проблема SET NOCOUNT ON отсутствовала.

person ErikE    schedule 22.04.2010
comment
Это избавило меня от головной боли, большое вам спасибо. У меня была запущена здоровенная команда SQL, и параметр NOCOUNT просто сработал! - person abbottdev; 02.02.2016
comment
Если мой ответ был вам полезен, проголосуйте за него, используя стрелку слева! - person ErikE; 02.02.2016

В дополнение к тому, что упомянул @ErikE, если ваш sproc содержит операторы PRINT (даже если они оставлены только для отладки), ADO также будет иметь корову, производящую ту же самую ошибку, которую вы видите.

person AngryHacker    schedule 26.04.2010