我正在寻找编写一个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格式化和源代码控制,因此它们始终采用相同的格式。 –