我正在尋找編寫一個PowerShell腳本,該腳本將遍歷SQL腳本文件的內容,查找包含TABLE提示的行,其中沒有WITH語句。添加關鍵字提示
例子:
SELECT * FROM dbo.Table (NOLOCK)
SELECT * FROM dbo.Table (INDEX=PK_Table)
SELECT * FROM dbo.Table (NOLOCK,INDEX=PK_Table)
SELECT * FROM dbo.Table (INDEX=PK_Table,NOLOCK)
我想編寫一個PowerShell腳本看起來對於那些提示並在TABLE HINT之前添加WITH
。
所以它們看起來像下面這樣:
SELECT * FROM dbo.Table WITH(NOLOCK)
SELECT * FROM dbo.Table WITH(INDEX=PK_Table)
SELECT * FROM dbo.Table WITH(NOLOCK,INDEX=PK_Table)
SELECT * FROM dbo.Table WITH(INDEX=PK_Table,NOLOCK)
到目前爲止,我有以下幾點:
foreach ($str in Get-Content "d:\script.sql") {
if ([regex]::IsMatch($str, "\({0,1}NOLOCK\)|\(,NOLOCK\{0,1}\)","IgnoreCase")) {
$strReplace = [regex]::Replace($str, "\({0,1}NOLOCK\)|\(,NOLOCK\{0,1}\)", "WITH $1")
write $strReplace
}
}
但是,它不插入WITH
到行中並保持匹配和行。
這也將不得不處理腳本如下所示:
SELECT Table1.*, Table2.* FROM dbo.Table1 Table1 (NOLOCK)
INNER JOIN dbo.Table2 Table2 (INDEX=PK_Table2, NOLOCK)
ON (Table2.Id = Table1.Id)
下面的建議
:我用下面的:
$expr = "(?=\([^)]*(?=(NOLOCK|INDEX=|INDEX\())[^)]*\))(?<!WITH\s+)"
if ([regex]::IsMatch($str, "(?=\([^)]*(?=(NOLOCK|INDEX=|INDEX\())[^)]*\))","IgnoreCase")) {
$replaced = $str -replace $expr,"WITH "
除非SQL語句結構一致,否則字符串解析將會很脆弱。考慮使用T-SQL腳本DOM:https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.transactsql.scriptdom.aspx –
謝謝,我試圖轉換1000多個程序,可能寫入沒有WITH關鍵字,以使它們與新版本的SQL Server保持一致。我找不到任何使用腳本DOM修復非編譯程序的示例。 –
另請注意,我們使用Redgate進行SQL格式化和源代碼控制,因此它們始終採用相同的格式。 –