我有一个访问vba代码,该代码在SQL Server 14.0中运行查询。但是大约要花20分钟才能停止查询,然后移到我的vba代码的下一行。
如果我将代码直接复制到SQL中并在其中运行,它将正常运行而不会出现问题。我最初以为这是由于连接或命令超时引起的,但是通常这应该会生成一条错误消息(即使如此,我也将超时设置为0以强制其无限期运行)。
请在下面找到我的代码,它使用游标在一系列表中循环以完成相同的任务。该任务涉及遍历“做一会儿”直到满足条件。此时,循环应结束并从下一个表开始。
它确实完成了3个游标循环,但随后又开始了下一个,然后才停止。
希望该代码有意义,访问时间很长,我不得不使用换行符将其全部分割,以使我的SQL字符串更易于解密和(尝试)调试。
''...Declare all relevant variables above...
On Error GoTo 0
SQL_STR1 = "DECLARE @STRSQL AS Varchar(max) " & vbCrLf & _
"DECLARE @TableName VARCHAR(50) " & vbCrLf & _
"DECLARE LoopVal CURSOR FOR SELECT TableName_ FROM [DBASE_NAME].[dbo].[a_Base_Year_Matrices] " & vbCrLf & _
"OPEN LoopVal " & vbCrLf & _
"FETCH NEXT FROM LoopVal INTO @TableName " & vbCrLf & _
"WHILE @@FETCH_STATUS = 0 " & vbCrLf & _
"BEGIN " & vbCrLf & _
SQL_STR2 = "SET @STRSQL = "
'...Create Some Tables...
"WHILE (@COUNTT < 1959 AND @COUNTTER < 150)" & vbCrLf & _
"BEGIN" & vbCrLf & _
'...Runs loops to meet conditions, once met drop unneeded tables and create final output...
SQL_STR3 = "EXEC(@STRSQL) " & vbCrLf & _
"FETCH NEXT FROM LoopVal INTO @TableName " & vbCrLf & _
"END " & vbCrLf & _
"CLOSE LoopVal " & vbCrLf & _
"DEALLOCATE LoopVal "
SQL_ALL = SQL_STR1 + SQL_STR2 + SQL_STR3
Set cnn = New ADODB.Connection
Set rs = New ADODB.Recordset
'Set SQL Server Location
cnn.ConnectionTimeout = 0
cnn.Open "Driver={SQL Server};Server=" & ServerName & ";Trusted_Connection=Yes;"
Set rs.ActiveConnection = cnn
DoCmd.SetWarnings False
cnn.CommandTimeout = 0
''Code to check to paste directly into SQL
''Debug.Print SQL_ALL
rs.Open SQL_ALL, cnn, adOpenForwardOnly
Next b
Next a
End Sub
答案 0 :(得分:3)
使用SET NOCOUNT ON;
语句启动SQL脚本;
这将禁止所有服务器消息传递,并将结果集放入您要打开的记录集中。
....
SQL_STR1 = "SET NOCOUNT ON; " & vbCrLf & _
"DECLARE @STRSQL AS Varchar(max) " & vbCrLf & _
"DECLARE @TableName VARCHAR(50) " & vbCrLf & _
"DECLARE LoopVal CURSOR FOR SELECT TableName_ FROM [DBASE_NAME].[dbo].[a_Base_Year_Matrices] " & vbCrLf & _
"OPEN LoopVal " & vbCrLf & _
"FETCH NEXT FROM LoopVal INTO @TableName " & vbCrLf & _
"WHILE @@FETCH_STATUS = 0 " & vbCrLf & _
"BEGIN " & vbCrLf & _
....
SET NOCOUNT ON
禁止在任何DML之后显示“受影响的xx行”消息。这是一个结果集,发送时,客户端(在这种情况下,您的ADO Recordset)必须对其进行处理。简而言之,记录集对象不会处理这些服务器消息-它需要一个游标,该游标代表基本表中的记录,查询结果或以前保存的Recordset。当您的记录集取回服务器消息时,它只会给您一个空的记录集。我猜想您的VBA不会期望一个空的记录集,并且当这种情况发生时,您有一些代码块被卡住了吗?不看所有VBA很难说。
将NoCount设置为ON将使服务器跳到记录集对象要处理的好东西(在这种情况下,是查询结果)。