从Access VBA发送时,SQL查询停止运行

时间:2018-10-31 17:18:54

标签: sql sql-server access-vba

我有一个访问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

1 个答案:

答案 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将使服务器跳到记录集对象要处理的好东西(在这种情况下,是查询结果)。