PowerShell SQL脚本并行执行的错误控制与执行顺序保障问题
PowerShell 多SQL实例批量执行脚本优化方案
优化后完整脚本
param( [string[]] $file_list, [string] $in_sql_server_instances_file_path ) # 前置校验:实例列表文件是否存在 if (!(Test-Path $in_sql_server_instances_file_path)) { Write-Output "错误:SQL实例列表文件 $in_sql_server_instances_file_path 不存在" exit 1 } # 前置校验:所有待执行SQL脚本是否存在 foreach ($sql_file in $file_list) { if (!(Test-Path $sql_file)) { Write-Output "错误:待执行SQL脚本 $sql_file 不存在" exit 1 } } # 读取SQL实例列表 $file_server_list = Get-Content -Path $in_sql_server_instances_file_path workflow execute-parallel { param( [string []] $sql_instances, [string []] $files_to_execute ) foreach -parallel -throttlelimit 8 ($sql_instance in $sql_instances) { inlineScript { $wf_sql_instance = $using:sql_instance $wf_files_to_execute = $using:files_to_execute Write-Output "===== 开始处理SQL实例:$wf_sql_instance =====" # 按传入顺序遍历执行SQL脚本 foreach ($file_to_execute in $wf_files_to_execute) { Write-Output "正在实例 $wf_sql_instance 上执行脚本:$file_to_execute" try { # 加上-ErrorAction Stop让执行错误触发终止异常 Invoke-Sqlcmd -ServerInstance "$wf_sql_instance" -Database "tempdb" -InputFile $file_to_execute -ErrorAction Stop Write-Output "脚本 $file_to_execute 在实例 $wf_sql_instance 执行成功" } catch { Write-Output "错误:脚本 $file_to_execute 在实例 $wf_sql_instance 执行失败,错误信息:$_" Write-Output "终止当前实例后续脚本执行,切换到下一个实例" # 跳出当前脚本循环,直接结束当前实例的处理 break } } Write-Output "===== 实例 $wf_sql_instance 处理完成 =====" } } } # 启动并行执行 execute-parallel -sql_instances $file_server_list -files_to_execute $file_list
关键需求实现说明
- 需求1(失败终止当前服务器后续执行):在脚本执行逻辑外层增加
try/catch捕获异常,一旦捕获到执行错误,直接调用break跳出当前实例的脚本循环,不再执行该实例后续的SQL脚本,自动进入下一个实例的处理流程。 - 需求2(完善错误控制逻辑):
- 增加前置校验逻辑,执行前先检查所有传入的SQL脚本文件是否存在,避免执行到中途才发现文件缺失
- 给
Invoke-Sqlcmd增加-ErrorAction Stop参数,将默认的非终止错误转为终止异常,确保所有执行错误都能被捕获 - 增加全流程日志输出,清晰标注当前处理的实例、执行的脚本、成功/失败状态以及错误详情
- 需求3&4(按指定顺序部署、确保a.sql在b.sql之前运行):PowerShell数组会严格保留参数传入时的顺序,脚本中遍历
$file_list/$files_to_execute时完全按照数组原有顺序执行,只要调用脚本时传入的-file_list参数按照'C:\Scripts\a.sql','C:\Scripts\b.sql'的顺序填写,就会严格保证a.sql先执行,执行成功后才会执行b.sql。
执行命令(无变化)
.\execute.ps1 -file_list 'C:\Scripts\a.sql','C:\Scripts\b.sql' -in_sql_server_instances_file_path 'C:\Scripts\sql_file.txt'
内容的提问来源于stack exchange,提问作者user3535468
相关产品推荐
相关产品推荐

