Scripting

我希望 Powershell 的 invoke-sqlcmd 忽略 SQL 執行錯誤

  • June 21, 2018

我編寫了一個 Powershell 腳本,它為伺服器上的所有數據庫編寫適當的 SQL 腳本,並為每個數據庫的內容創建 BCP 文件。這是為了允許將數據庫從較高級別的 SQL 恢復到無法進行備份和恢復的較低級別(但沒有使用其他不兼容的特性或功能)。這很好,在目標伺服器上自動執行它們是有問題的。

創建的每個腳本都包含小問題。例如,如果表格已經存在,表格腳本都以按名稱刪除表格開始。這在 SSMS 中很好,因為如果表不存在,您可以刪除該行以避免“不存在或您沒有權限”錯誤。您還需要刪除其他內容,例如通過執行其他腳本來創建已經存在的索引,這些腳本從同一數據庫中創建其他表。

Invoke-sqlcmd -inputfile dbo.SomeTable.sql 在這些錯誤上停止並失敗。我怎樣才能讓invoke-sqlcmd忽略它們並只做它可以做的事情(知道這很好),或者暫時讓SQL容忍這些而不引發停止錯誤,或者我還能用什麼來以程式方式應用腳本SQL伺服器在沒有人工干預的情況下生成到 SQL 伺服器?

我怎樣才能

$$ … $$暫時使 SQL 能夠容忍這些,並且不會引發停止錯誤

在嘗試刪除或創建對象之前測試對像是否存在。這樣,如果 DROP 或 CREATE 本身失敗而不是發生衝突,您仍然會拋出錯誤。

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[YourTableName]') AND type in (N'U'))
DROP TABLE [dbo].[YourTableName]
GO

IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[YourTableName]') AND type in (N'U'))
CREATE TABLE [dbo].[YourTableName] ( ... )

[注意:此語法來自Microsoft.SqlServer.Management.Smo.Scripter生成的腳本。]

我假設您的 PowerShell 腳本正在使用Microsoft.SqlServer.Management.SMO.Scripter? 為什麼不指定Scripter.Options.IncludeIfNotExists = $true?您可以獲得與使用 SSMS 的 Generate Scripts 工具獲得的所有相同選項。做這樣的事情:

Add-Type -AssemblyName 'Microsoft.SqlServer.Smo, Version=14.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91'

$ServerName = 'servername'
$DatabaseName = 'databasename'
$ScriptFileName = 'C:\scriptfilename.sql'
if (Test-Path $ScriptFileName) {
   Remove-Item $ScriptFileName
}

$SMOServer = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -ArgumentList $ServerName
$SMODatabase = $SMOServer.Databases.Item($DatabaseName)

$Scripter = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Scripter -ArgumentList $SMOServer
$Scripter.Options.AllowSystemObjects = $false
$Scripter.Options.IncludeHeaders = $true
$Scripter.Options.IncludeIfNotExists = $true
$Scripter.Options.Indexes = $true
$Scripter.Options.Permissions = $true
$Scripter.Options.ScriptBatchTerminator = $true
$Scripter.Options.ScriptSchema = $true
$Scripter.Options.TargetServerVersion = [Microsoft.SqlServer.Management.Smo.SqlServerVersion]::Version100
$Scripter.Options.WithDependencies = $true
$Scripter.Options.FileName = $ScriptFileName
$Scripter.Options.AppendToFile = $true
$Scripter.Options.ToFileOnly = $true

# Drop all tables
$Scripter.Options.ScriptData = $false # Don't script data
$Scripter.Options.ScriptDrops = $true # Script drop statements
foreach ($SMOTable in $SMODatabase.Tables) {
   $Scripter.EnumScript($SMOTable.Urn)
}

# Create all tables with data, indexes, and permissions
$Scripter.Options.ScriptData = $true # Script table data
$Scripter.Options.ScriptDrops = $false # Script create statements
foreach ($SMOTable in $SMODatabase.Tables) {
   $CreateScripter.EnumScript($SMOTable.Urn)
}

這使用 SQL Server 2008 語法 ( Version100) 編寫表腳本。我正在使用 Sql Server Management Studio 17 附帶的庫版本。

引用自:https://dba.stackexchange.com/questions/208309