2012-10-31 111 views
1

有誰知道如何設置Invoke-SqlCmd QueryTimeout超過65535?Invoke-SqlCmd QueryTimeout

微軟表示他們已經在Denali修復了它,但我們仍然在使用SQL 2008 R2和最新的服務包。

http://connect.microsoft.com/SQLServer/feedback/details/551799/invoke-sqlcmd-querytimeout-0-still-times-out

基本上,我們正試圖備份或使用PowerShell還原數據庫。我們的一些數據庫非常大,因此完成這項工作需要超過65535個數據庫。

有人建議我們應該在PowerShell中使用超時的ADO.NET。但我不知道我們是否有任何解決方法爲Invoke-SqlCmd ...

+0

您確定要使用'Invoke-SqlCmd'嗎?如果您無法將客戶端升級到SQL 2012,則可以嘗試通過直接使用'cmd/c'直接執行'SQLCMD'或使用SMO執行備份/恢復來解決此問題。 –

+0

將查詢超時設置爲零應使其等待,直到命令完成,無論需要多長時間。 – JamieSee

回答

0

您可以編寫自己的Invoke-SqlCmd版本,直接使用System.Data.SqlClient對象並執行任何您想要的操作。有很多關於如何實現此功能的示例,其中包括invoke-sqlcmd2,這是專門爲解決QueryTimeout錯誤而編寫的,它託管在Microsoft的腳本庫上。如果您不想部署這樣的腳本,則可以將相關代碼直接集成到備份腳本中。

或者,您應該可以使用SMO來備份數據庫。 IIRC,querytimeout錯誤不會影響SMO。

+0

默認情況下,包含備份的SMO查詢超時時間爲10分鐘。如果你想要更長時間,你需要設置它。 –

1

您可以使用以下功能來定製自己的查詢超時會話超時限制(在定義你可以給你自己期望的值參數)

function Invoke-SqlCommand 
{ 
    [CmdletBinding()] 
    param( 
    [Parameter(Position=0, Mandatory=$true)] [string]$ServerInstance, 
    [Parameter(Position=1, Mandatory=$false)] [string]$Database, 
    [Parameter(Position=2, Mandatory=$false)] [string]$Query, 
    [Parameter(Position=3, Mandatory=$false)] [string]$Username, 
    [Parameter(Position=4, Mandatory=$false)] [string]$Password, 
    [Parameter(Position=5, Mandatory=$false)] [Int32]$QueryTimeout=600, 
    [Parameter(Position=6, Mandatory=$false)] [Int32]$ConnectionTimeout=15, 
    [Parameter(Position=7, Mandatory=$false)] [ValidateScript({test-path $_})] [string]$InputFile, 
    [Parameter(Position=8, Mandatory=$false)] [ValidateSet("DataSet", "DataTable", "DataRow")] [string]$As="DataRow" 
    ) 

    if ($InputFile) 
    { 
     $filePath = $(resolve-path $InputFile).path 
     $Query = [System.IO.File]::ReadAllText("$filePath") 
    } 

    $conn=new-object System.Data.SqlClient.SQLConnection 

    if ($Username) 
    { $ConnectionString = "Server={0};Database={1};User ID={2};Password={3};Trusted_Connection=False;Connect Timeout={4}" -f $ServerInstance,$Database,$Username,$Password,$ConnectionTimeout } 
    else 
    { $ConnectionString = "Server={0};Database={1};Integrated Security=True;Connect Timeout={2}" -f $ServerInstance,$Database,$ConnectionTimeout } 

    $conn.ConnectionString=$ConnectionString 

    #Following EventHandler is used for PRINT and RAISERROR T-SQL statements. Executed when -Verbose parameter specified by caller 
    if ($PSBoundParameters.Verbose) 
    { 
     $conn.FireInfoMessageEventOnUserErrors=$true 
     $handler = [System.Data.SqlClient.SqlInfoMessageEventHandler] {Write-Verbose "$($_)"} 
     $conn.add_InfoMessage($handler) 
    } 

    $conn.Open() 
    $cmd=new-object system.Data.SqlClient.SqlCommand($Query,$conn) 
    $cmd.CommandTimeout=$QueryTimeout 
    $ds=New-Object system.Data.DataSet 
    $da=New-Object system.Data.SqlClient.SqlDataAdapter($cmd) 
    [void]$da.fill($ds) 
    $conn.Close() 
    switch ($As) 
    { 
     'DataSet' { Write-Output ($ds) } 
     'DataTable' { Write-Output ($ds.Tables) } 
     'DataRow' { Write-Output ($ds.Tables[0]) } 
    } 

} 

希望它幫助。

相關問題