代码之家  ›  专栏  ›  技术社区  ›  Gavin

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

  •  0
  • Gavin  · 技术社区  · 6 年前

    我有一个access vba代码,它在SQLServer14.0中运行查询。不过,在停止查询并转到vba代码的下一行之前,大约需要20分钟。

    如果我将代码直接复制到SQL中并在那里运行它,它就可以正常运行而不会出现任何问题。我最初认为这是由于连接或命令超时造成的,但是通常这应该会生成错误消息(即使如此,我还是将超时设置为0以强制它们无限期运行)。

    请在下面找到我的代码,它使用一个游标在一系列表中循环来完成相同的任务。这个任务包括循环执行一段时间,直到满足条件为止。此时,循环应该结束并从下一个表开始。

    它确实完成了3个游标循环,但是它开始下一个循环,然后就停止了。

    ''...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 回复  |  直到 4 年前
        1
  •  3
  •   ArcherBird    6 年前

    SET NOCOUNT ON; 声明;

    ....
    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对象不处理这些服务器消息—它需要一个表示基表记录、查询结果或以前保存的记录集的游标。当您的记录集收到服务器消息时,它只会给您一个空的记录集。我猜你的VBA不希望有一个空的记录集,当这种情况发生时,你有一些代码块被卡住了?很难说没有看到所有的VBA。

    设置NoCount使服务器跳到recordset对象要处理的好东西(在本例中是查询的结果)。

    推荐文章