我使用以下代码来处理SQL脚本并使用GO命令将其拆分:
[string]$batchDelimiter = "[gG][oO]"
$scriptContent = Get-Content $sqlScript | Out-String
$batches = $scriptContent -split "\s*$batchDelimiter\s*\r?\n"
foreach($batch in $batches)
{
if(![string]::IsNullOrEmpty($batch.Trim()))
{
$SqlCmd.CommandText = $batch
$reader = $SqlCmd.ExecuteNonQuery()
}
}
我遇到的问题是当GO命令出现在注释块的中间时:
/*
IF OBJECT_ID('AmyTempMapRetroDateFK') IS NOT NULL
DROP FUNCTION AmyTempMapRetroDateFK
GO
*/
有没有办法在处理脚本之前删除所有注释块?我在c#中看到了一些例子,但对于Powershell却没有。
答案 0 :(得分:1)
假设没有嵌套注释(PSv3 +语法):
(Get-Content -Raw $sqlScript) -split '(?s)/\*.*?\*/' -split '\r?\ngo\r?\n' -notmatch '^\s*$' |
ForEach-Object { $SqlCmd.CommandText = $_.Trim(); $reader = $SqlCmd.ExecuteNonQuery() }
注意:如果最后一行有可能不以换行符结束,
使用'\r?\ngo(\r?\n|$)
代替
'\r?\ngo\r?\n'
Get-Content -Raw
,自PSv3起可用,将整个文件读入单字符串 - 它更简单,效率更高,相当于Get-Content $sqlScript | Out-String
-split '(?s)/\*.*?\*/'
按/* ... */
跨度拆分输入字符串;请注意内联选项(?s)
,这也是.
匹配换行符所必需的选项;需要非贪婪量词.*?
才能匹配 next */
实例;结果是一个排除了注释块的行块数组。
-split '\r?\ngo\r?\n'
然后通过单词go
进一步拆分该数组,后面跟一个换行符。
请注意,默认情况下-split
为case-不敏感,因此您无需担心GO
等案例变体。
(您可以使用别名-isplit
使不区分大小写的行为更明确;类似地,
-csplit
可用于案例敏感匹配。)
-notmatch '^\s*$'
从结果数组中过滤掉空白/空元素,并通过管道(|
)发送过滤后的数组。
ForEach-Object
cmdlet然后通过自动变量$_
对每个数组元素(现在包含单个SQL命令)进行操作,该变量始终代表手头的输入对象。
答案 1 :(得分:-1)
也许您可以拆分/*
并加入生成的数组。
然后将其拆分为*/
,并加入生成的数组。
使用`r`n
(回车符,换行符)分隔符更容易阅读联接