2010-04-22 1 views
2

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

Вот код, чтобы продемонстрировать эту проблему:

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 

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

Я побежал след, и это то, что библиотека ADO фактически отправки на сервер:

declare @p1 int 
set @p1=1 
declare @p2 datetime 
set @p2=''2010-04-22 15:31:07:770'' 
exec ErrorAlertCollect @[email protected] output,@[email protected] 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 @[email protected] output,@[email protected] 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 работать нормально.

... О, мой. Я просто понял это. Я полагаю, что это стоит публикации в любом случае.

+0

'' 'datetime''' - просто известная ошибка в профилировщике (исправлено в SP2, я думаю) –

+0

Спасибо. Странно, что профайлер будет сообщать о чем-то отличном от реального. Я проверю уровень Service Pack на сервере. – ErikE

ответ

2

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

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

+0

Это спасло мне головную боль, большое спасибо. У меня была мощная команда SQL, и команда NOCOUNT только что сработала! – abbottdev

+0

Если бы мой ответ был полезен вам, пожалуйста, проголосуйте, используя стрелку слева! – ErikE

2

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