我在针对 SQL Server 2005 数据库运行 VB6 中的 ADO 命令时遇到莫名其妙的错误。
这里有一些代码来演示该问题:
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 @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 不支持这种语法。实际SP执行语句中只能使用DEFAULT关键字。
我应该注意,从上面的语句中删除额外的单引号可以使 SP 正常运行。
...天啊。我刚刚想通了。我想无论如何都值得发布。
最佳答案
答案是,存储过程需要在顶部SET NOCOUNT ON
,因为 ADO 在收到“受影响的行”响应时立即停止,并且存储过程在最终选择。
我不知道为什么跟踪显示的 ADODB 语法在单独提交时无法正确运行,但显然 ADODB 库的查询没有出现错误。整个问题是 SET NOCOUNT ON
缺失。
关于sql-server - VB6 ADO 命令到 SQL Server,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2695155/