2017-06-22 56 views
0

我在Excel 2016中使用下面的VBA查詢exacutes一個MS SQL存儲過程中,有時會順利執行,並返回記錄集,但更多的時候我得到一個錯誤[Microsoft][ODBC SQL Server Driver] query timeout expiredExcel的VBA:ODBC SQL Server驅動程序查詢超時過期

與此同時,當我們去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 

任何建議表示讚賞。 喬爾

+0

您是否嘗試過更新的ODBC驅動程序(Native Client xx或ODBC驅動程序xx for SQL Server)?任何可疑的日誌數據? – BitAccesser

+0

我將驅動程序更改爲我安裝的另一個版本{ODBC驅動程序13 for SQL Server},同樣的錯誤。 – joell

+0

這個[怎麼做我運行一個存儲過程與參數從excel-vba字符串](https://stackoverflow.com/questions/31986552/how-doi-i- run-a-stored-procedure-with-parameters-from-excel-vba-string) – BitAccesser

回答

0

一種可能的解決辦法是加長的連接命令超時值。您當前的腳本將值設爲0.這可能會增加。在SSMS中運行查詢應該讓您大致瞭解完成查詢所需的時間。然後,相應地調整該值。

cm.CommandTimeout = 100 
+0

根據以下文檔,CommandTimeout = 0表示沒有限制。 https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.commandtimeout(v=vs.110).aspx – joell

+0

嘗試'cn.CommandTimeout = 0'作爲'Connection.CommandTimeout'已對Command.CommandTimeout或提供程序和數據源不起作用,不支持[commandtimeout-property-ado](https://docs.microsoft.com/zh-cn/sql/ado/reference/ado-api/commandtimeout- property-ado) – BitAccesser

0

經過一些更多的關於這個問題和我以前的答案的評論後,這裏有一些額外的觀點。爲了BitAccesser,cn.CommandTimeout相同Connection.CommandTimeout因爲最初提交的代碼已經尺寸並設置cn對象作爲ADODB.Connection。另外值得注意的是ConnectionTimeoutCommandTimeout之間的差異。連接超時是網絡級別,而命令超時是SQL Server級別。在這種情況下,即使ADODB.Command對象被實例化,它也不會被使用。另一點與連接字符串有關。連接超時可以在連接字符串中引用,但通常不會使用。連接將默認爲15秒。所以,它的價值顯然重置了這些屬性。

Cn.CommandTimeout = 50 
    Cn.ConnectionTimeout = 50 
+0

我對ADODB不熟悉,所以'CommandTimeout = 0'不像預期的那樣工作(無限制)?我只是在上面的鏈接中閱讀了文檔,它說'Connection'和'Command'都有一個獨立於其他'CommandTimeout'屬性。在提供者和數據源(同一文檔)中支持'CommandTimeout'怎麼樣?這可能會影響他的設置(使他們無用)? – BitAccesser

+0

經過更多的挖掘,我發現我的查詢中的一個聯合表正被其他用戶在插入數據時使用。我懷疑當時表被鎖定導致查詢超時。我還加了NOLOCK,到目前爲止沒有運氣。 – joell

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