我正在根據 String GO將我的 SQL 檔案分成批處理。我使用了 stackoverflow 執行緒How do I split file on batch using powershell as reference 注意到這個正則運算式在少數情況下不起作用
- 如果在單引號中找到 go,則字串將被拆分。(我想避免對單引號內的任何文本進行拆分)
- 另一種情況是當我使用像 Declare @go 這樣的 go on Declare 陳述句時
我不熟悉正則運算式模式。因此,我嘗試在 regex 上搜索一些在線檔案,并提出了在單引號中查找任何內容的模式,以及如何在拆分時忽略檔案中的 @go。下面是正則運算式
- ('([\s\S]*?)') - 獲取單引號中的字串,但我不確定如何將此匹配項添加到當前正則運算式模式中以排除
- (?<![\S]) (?:\bGO\b) - 當任何非空白字符位于 sql 檔案下方處理 @go 的 GO 字串之前時,可以避免拆分
SQL檔案內容:
select * from testTbl; GO
select * from testTbl2;
GO
Declare @go varchar(15) = 'IGo test'
select @go
GO
SELECT 'go', ' go ', 'asdv Igo asdsad',
'
go
'
GO
create table #Temp
(
IdGo int,
GoId Varchar(50)
)
select * from #Temp
drop table #Temp
GO
PowerShell 腳本行:
$batches = ( $scriptData -split "(?:\bGO\b)" ) | % { $_ "`r`nGO" }
注意:var 中$scriptData包含 SQL 檔案內容。
這是一種正確的方法,或者當字串用單引號括起來時,我們如何排除拆分?有沒有更清潔的方法來做到這一點?
僅供參考:一旦我找到解決方案,我將更新另一個執行緒的答案。或者,如果有人認為它是重復的,我很樂意更新另一個執行緒并洗掉它。
更新:所需的輸出:
select * from testTbl;
GO
select * from testTbl2;
GO
Declare @go varchar(15) = 'IGo test' select @go
GO
SELECT 'go', ' go ', 'asdv Igo asdsad','go'
GO
create table #Temp ( IdGo int, GoId Varchar(50) ) select * from #Temp drop table #Temp
GO
uj5u.com熱心網友回復:
為了有力決議您輸入批,你需要一個語言決議器能夠可靠地識別語法元素-正則運算式是不復雜的足夠您輸入的語法建模。
在沒有T-SQL分析器,[1] 你可以很可能逃脫的PowerShell自己的語言決議器,[System.Management.Automation.Language.Parser]鑒于有兩種語言之間高層次的共性,所以應該能夠識別隔離,非- -輸入中的@前綴GO標記:
警告重新評論支持:
由于 T-SQL 的注釋結構與 PowerShell 不同,因此使用PowerShell 決議器會為comments 中的(隔離的)子字串產生誤報
GO。因此,下面的解決方案使用基于正則運算式的預處理,洗掉所有注釋(通過涉及后處理步驟的額外作業,可以保留注釋),但這并不完全可靠,并且依賴于以下假設:
- 帶引號的字串中不會出現類似注釋的結構。
- 塊引號 (
/* ... */) 不是嵌套的。
(通過使用平衡組定義的更復雜的正則運算式,您可能能夠克服此特定限制)。
# Get the file's content and preprocess it by *removing comments*,
# to prevent GO instances inside them from yielding false positives.
# CAVEAT: This isn't fully robust, but may work well enough in practice.
# See the notes above this code snippet.
$fileContent = (Get-Content -Raw t.txt) -replace '(?m)^\s*--.*' -replace '(?s)/\*.*?\*/'
# Parse the file content into an AST (Abstract Syntax Tree),
# as if it were PowerShell code.
$ast = [System.Management.Automation.Language.Parser]::ParseInput($fileContent, [ref] $null, [ref] $null)
# Get all locations - in terms of line and column number - of isolated,
# unquoted GO tokens.
$locations =
$ast.FindAll({ $args[0].Extent.Text -eq 'go' }, $false) |
Select-Object -ExpandProperty Extent |
Select-Object StartLineNumber, StartColumnNumber -Unique
# Split the file content into batches by the locations of the
# isolated, unquoted GO tokens, resulting in an array of strings
# each representing a batch, stored in $batches.
$thisBatch = ''
$lineNo = $locNdx = 0
[string[]] $batches =
$fileContent -split '\r?\n' | ForEach-Object {
if ( $lineNo -eq $locations[$locNdx].StartLineNumber) {
$fromCol = 0
do {
$thisBatch $_.Substring($fromCol, $locations[$locNdx].StartColumnNumber - $fromCol 2 - 1)
$thisBatch = ''
$fromCol = $locations[$locNdx].StartColumnNumber 2 - 1
} while ($locations[ $locNdx].StartLineNumber -eq $lineNo)
if ($fromCol -lt $_.Length) {
$thisBatch = $_.Substring($fromCol) "`n"
}
} else {
$thisBatch = "$_`n"
}
}
# If the last batch wasn't terminated with a GO, we must add it now.
# Remove "`nGO" if you don't want to append a terminating GO.
if ($thisBatch.Trim()) { $batches = $thisBatch "`nGO" }
# Diagnostic output, to show the resulting batches:
$batches -join "`n-----------------`n"
以上輸出,基于您的樣本輸入:
select * from testTbl; GO
-----------------
select * from testTbl2;
GO
-----------------
Declare @go varchar(15) = 'IGo test'
select @go
GO
-----------------
SELECT 'go', ' go ', 'asdv Igo asdsad',
'
go
'
GO
-----------------
create table #Temp
(
IdGo int,
GoId Varchar(50)
)
select * from #Temp
drop table #Temp
GO
注意:
沒有嘗試將每個批次壓縮為單行表示,但這應該不是問題。
該代碼還正確處理了一行上的多個批次,例如以下示例中的兩個完整和一個未完成的批次:
select * from testTbl0;GO select * from testTbl1 GO Declare @go varchar(15) = 'IGo test'此外,還包括最后一批碰巧沒有被終止的批次
GO。
[1]注:“GO不是Transact-SQL陳述句;它是由公認的命令sqlcmd和osql實用工具和SQL Server Management Studio中代碼編輯器。” - 請參閱檔案
檔案還指出“Transact-SQL 陳述句不能與 GO 命令占用同一行。”,這將使問題中的第一個樣本批次在技術上無效,但 Raj(OP)報告說它有效盡管如此。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/370388.html
