有谁知道如何将 Invoke-SqlCmd QueryTimeout 设置为超过 65535?
微软表示他们已经在 Denali 中修复了它,但我们仍在使用带有最新服务包的 SQL 2008 R2。
基本上,我们正在尝试使用 powershell 备份或恢复数据库。我们的一些数据库非常大,因此完成这项工作需要超过 65535 个。
有人建议我们应该在 powershell 中使用带有超时的 ADO.NET。但我想知道我们是否对 Invoke-SqlCmd 有任何解决方法...
有谁知道如何将 Invoke-SqlCmd QueryTimeout 设置为超过 65535?
微软表示他们已经在 Denali 中修复了它,但我们仍在使用带有最新服务包的 SQL 2008 R2。
基本上,我们正在尝试使用 powershell 备份或恢复数据库。我们的一些数据库非常大,因此完成这项工作需要超过 65535 个。
有人建议我们应该在 powershell 中使用带有超时的 ADO.NET。但我想知道我们是否对 Invoke-SqlCmd 有任何解决方法...
调用-Sqlcmd -query 'select * from largeDb' -QueryTimeout 0
-QueryTimeout 0:将使您的 cmdlet超时。
AFAIK 很快,这个错误就会得到解决。
您可以使用以下函数自定义您自己的查询超时和会话超时限制(同时定义您可以给您自己想要的值的参数)
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]) }
}
}
希望能帮助到你。
您可以编写自己的 Invoke-SqlCmd 版本,该版本直接使用 System.Data.SqlClient 对象并使用它做任何您想做的事情。有很多示例说明如何执行此操作,包括invoke-sqlcmd2,它是专门为绕过 QueryTimeout 错误而编写的,托管在 Microsoft 的脚本库中。如果您不想部署这样的脚本,您可以直接将相关代码集成到您的备份脚本中。
或者,您应该能够使用 SMO 来备份数据库。IIRC,querytimeout 错误不会影响 SMO。