PowerShell技术问询:验证SQL删除语句是否早于对应插入语句
验证SQL脚本中Delete语句是否在对应Insert语句之前(PowerShell实现)
核心思路
通过Select-String返回的MatchInfo对象直接提取表名、行号和文件路径,按表名+文件路径关联Insert和Delete条目,对比两者的行号判断顺序是否合规。
完整实现代码
# 替换为你的实际路径 $packagepath = "你的路径" # 获取所有Insert语句的匹配结果 $insertinto = Get-ChildItem "$packagepath\Init\" -Include 03_Init_*.txt -Recurse | Select-String -Pattern "insert into " # 获取所有Delete语句的匹配结果 $deletefrom = Get-ChildItem "$packagepath\Init\" -Include 03_Init_*.txt -Recurse | Select-String -Pattern "delete from " # 处理Insert语句,提取结构化信息 $insertEntries = $insertinto | ForEach-Object { if ($_.Line -match 'insert into\s+([^\s;]+)') { [PSCustomObject]@{ TableName = $matches[1] LineNumber = $_.LineNumber FilePath = $_.Path } } } # 处理Delete语句,提取结构化信息 $deleteEntries = $deletefrom | ForEach-Object { if ($_.Line -match 'delete from\s+([^\s;]+)') { [PSCustomObject]@{ TableName = $matches[1] LineNumber = $_.LineNumber FilePath = $_.Path } } } # 逐表检查Delete与Insert的顺序 foreach ($insert in $insertEntries) { $matchingDelete = $deleteEntries | Where-Object { $_.TableName -eq $insert.TableName -and $_.FilePath -eq $insert.FilePath } switch ($true) { (-not $matchingDelete) { Write-Warning "文件 $($insert.FilePath) 中,表 $($insert.TableName) 的Insert语句(行$($insert.LineNumber))无对应Delete语句" break } ($matchingDelete.LineNumber -ge $insert.LineNumber) { Write-Error "文件 $($insert.FilePath) 中,表 $($insert.TableName) 的Delete语句(行$($matchingDelete.LineNumber))未位于Insert语句(行$($insert.LineNumber))之前" break } default { Write-Host "文件 $($insert.FilePath) 中,表 $($insert.TableName) 的Delete语句(行$($matchingDelete.LineNumber))位于Insert语句(行$($insert.LineNumber))之前,符合要求" -ForegroundColor Green } } }
关键细节说明
- 利用MatchInfo对象属性:
Select-String返回的不是纯文本,而是包含Line(行内容)、LineNumber(行号)、Path(文件路径)的对象,直接调用属性比解析字符串更可靠。 - 正则提取表名:使用
insert into\s+([^\s;]+)和delete from\s+([^\s;]+)匹配表名,跳过空格,遇到空格或分号停止,兼容带分号的Delete语句格式。 - 多维度匹配:同时匹配
TableName和FilePath,避免不同文件中同名表的干扰。 - 清晰的输出提示:用不同颜色和类型的输出区分合规、缺失、顺序错误三种情况,便于快速定位问题。
内容的提问来源于stack exchange,提问作者Karel
相关产品推荐
相关产品推荐

