2010-04-22 81 views
2

我发现了一个莫名其妙的错误,在VB6运行ADO命令对SQL Server 2005数据库。VB6 ADO命令到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不支持这种类型的语法。您只能在实际的SP执行语句中使用DEFAULT关键字。

我要指出,从上面的语句删除多余的单引号使得SP运行正常。

...哦,我的。我只是想出了它。无论如何,我想这是值得发帖的。

+0

的'“” datetime'''是在分析器(固定在SP2中,我认为)只是一个已知的bug – 2010-04-23 11:49:42

+0

感谢。奇怪的是,剖析器会报告与真实情况不同的东西。我将检查服务器的服务包级别。 – ErikE 2010-04-24 06:12:07

回答

2

答案是存储过程需要在顶部有SET NOCOUNT ON,因为ADO在获得“受影响的行”响应时停止,并且存储过程在最终选择之前有更新语句。

我不知道为什么跟踪显示ADODB的语法,当它自己提交时无法正确运行,但显然ADODB库没有收到其查询错误。整个问题是SET NOCOUNT ON失踪。

+0

这救了我头疼,太感谢你了。我有一个大量的SQL命令运行,并提供了NOCOUNT选项! – abbottdev 2016-02-02 17:09:12

+0

如果我的回答对您有用,请使用左侧的箭头进行投票! – ErikE 2016-02-02 17:12:05

2

除了@ErikE提到的内容,如果你的存储过程包含PRINT语句(即使只是用于调试),ADO也会有一头牛,产生与你所看到的完全相同的错误。