Excel VBA:ODBC SQL服务器驱动程序查询超时已过期

时间:2017-06-22 20:11:04

标签: sql-server excel vba excel-vba

我在Excel 2016中使用了以下VBA查询来说明MS Sql存储过程,有时它会顺利执行并返回记录集,但更多时候我会收到错误[Microsoft][ODBC SQL Server Driver] query timeout expired

在我们访问SSMS并执行查询的同时,它运行没有问题。

这假设问题是由Excel / VB而不是SQL或查询本身引起的。

搜索此错误会导致检查网络防火墙,但我们尝试在没有防火墙的其他计算机上,问题仍然存在。

这是VB代码:

  
    Public Sub GetDataset2()

    Dim cn As ADODB.Connection
    Dim cm As Object
    Dim rs As ADODB.Recordset
    Dim UID, PWD, DB As String
    UID = "userId"
    PWD = "passworD"
    DB = "192.168.1.1"

    Set cn = New ADODB.Connection
    Set cm = CreateObject("ADODB.Command")

    cm.CommandTimeout = 0
    cn.Open ("Driver={SQL Server};Server=" & DB & ";Database=myDatabaseName;Trusted_Connection=no;Timeout=900;Uid=" & UID & ";Pwd=" & PWD)
    Set rs = cn.Execute("Get_dataset2 '" & Format(Range("dateFrom"), "yyyy-mm-dd") & "' ,'" & Format(Range("dateTo"), "yyyy-mm-dd") & "' ")

Dim lRow As Long

'Find the last non-blank cell in column A(1)
    lRow = Sheets("data").Cells(Rows.Count, 1).End(xlUp).Row
    lr = "A" & lRow + 1
        Sheets("data").Range(lr).CopyFromRecordset rs  'insert data

cn.Close

End Sub

任何建议表示赞赏。 乔尔

3 个答案:

答案 0 :(得分:0)

一种可能的解决方案是延长连接命令超时值。您当前的脚本的值设置为0.这可能会增加。在SSMS中运行查询应该可以大致了解完成查询所需的时间。然后,相应地调整值。

    cm.CommandTimeout = 100

答案 1 :(得分:0)

在对我之前的答案中的问题和评论进行了一些更多考虑之后,还有一些补充要点。对于BitAccesser,Options +FollowSymLinks -MultiViews Options -Indexes AcceptPathInfo Off RewriteEngine on RewriteBase / #Force from http to https RewriteCond %{SERVER_PORT} 80 RewriteCond %{HTTP_HOST} !^example.com$ [OR] RewriteCond %{HTTP_HOST} !^www.example.com$ RewriteRule ^(.*)$ https://www.example.com/$1 [R=301] RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}\.php -f RewriteRule ^(.*)$ $1.php cn.CommandTimeout相同,因为最初提交的代码已经标注尺寸,并将Connection.CommandTimeout对象设置为cn。另外值得注意的是ADODB.ConnectionConnectionTimeout之间的差异。连接超时是网络级别,而命令超时是SQL Server级别。在这种情况下,即使实例化CommandTimeout对象,也不会使用它。另一点涉及连接字符串。连接超时可以在连接字符串中引用,但通常不使用。连接默认为15秒。因此,值得明确重置这些属性。

ADODB.Command

答案 2 :(得分:0)

经过数周的各种代码更改测试后,我们发现在将SQL调用更改为QueryTable方法而不是CopyFromRecordset方法时,它的工作正常。

所以如果有人在将来需要它,我会粘贴代码。

Sub GetDataset3()

Dim cn As ADODB.Connection
Dim Rs As ADODB.Recordset
Dim UID, PWD, SRV As String
UID = "userId"
PWD = "passworD"
SRV = "192.168.1.1"

If Sheets("data").QueryTables.Count = 0 Then
     Sheets("data").Cells.Select
     Selection.ClearContents

     Dim Str As String 'adds backround query
     Str = ""
     For Each cell In Range("A1:A10").Cells
     Str = Str & Chr(10) & cell
    Next

      With Sheets("data").QueryTables.Add(Connection:="ODBC;UID=;PWD=;DRIVER=SQL 
        Server;SERVER=SRV", Destination:=Range("a2"))
        .CommandText = "select 1"
        'BackgroundQuery = True
        '.Refresh BackgroundQuery = True
        .FieldNames = False
        .AdjustColumnWidth = False
      End With
End If

 With Sheets("data").QueryTables(1)
   .Connection = "ODBC;DRIVER=SQL Server;SERVER=" & SRV & 
   ";database=myDatabaseName;UID=" & UID & ";Pwd=" & PWD & 
   ";Trusted_Connection=no;APP=Microsoft Office"
   .CommandText = ("Get_dataset2 '" & Range("dateFrom") & "' ,'" & 
    Range("dateTo") & "' ")
    BackgroundQuery = True
    .Refresh BackgroundQuery:=False

 End With

End Sub