我使用下面的代码来处理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中没有。
3条答案
按热度按时间hsvhsicv1#
假设没有 * nested * 注解(PSv3+语法):
注意:如果最后一行可能没有以换行符结束,请使用
'\r?\ngo(\r?\n|$)
而不是'\r?\ngo\r?\n'
Get-Content -Raw
自PSv3开始提供,它将整个文件读取到一个 * 单个 * 字符串中-它是Get-Content $sqlScript | Out-String
的更简单、更高效的等价物-split '(?s)/\*.*?\*/'
将输入字符串拆分为/* ... */
个跨度;注意内联选项(?s)
,它也是使.
匹配换行符所必需的;需要非贪婪量词.*?
来仅匹配到 * 下一个 **/
示例;结果是排除注解块的行块阵列。-split '\r?\ngo\r?\n'
然后通过单词go
前后加一个换行符来进一步分割该数组。请注意,
-split
在默认情况下是大小写不敏感的,因此您不必担心GO
这样的大小写变化。(You可以使用别名
-isplit
来使不区分大小写的行为更加明确;类似地,-csplit
可用于 * 区分大小写 * 的匹配。)-notmatch '^\s*$'
从结果数组中过滤出空白/空元素,并通过管道发送过滤后的数组(|
)。ForEach-Object
cmdlet通过自动变量$_
对每个数组元素(现在包含一个单独的SQL命令)进行操作,该变量始终表示手头的输入对象。mpbci0fu2#
标记为最佳答案的解决方案的简化版本,在此修改以删除PS注解块:
不确定为什么GO语句会在这里发生干扰。应用到SQL注解块,应该会这样做:
sd2nnvve3#
也许你可以在
/*
上拆分并加入得到的数组,然后在*/
上拆分并加入得到的数组。使用``r
n
(回车、换行符)分隔符可以更容易地读取连接