PowerShell部署DACPAC遇执行超时错误,寻求解决方案
问题梳理
使用PowerShell调用Microsoft.SqlServer.Dac.dll部署DACPAC时出现执行超时错误,尝试设置CommandTimeout无效,且LongRunningCommandTimeout属性不存在;但最新版本(162.0.52.1)的sqlpackage.exe可正常部署同一DACPAC,旧版sqlpackage.exe同样会超时。
解决方案
1. 确保加载与最新sqlpackage.exe匹配的Dac.dll版本
sqlpackage.exe本质基于Microsoft.SqlServer.Dac.dll开发,二者版本必须严格对应。若PowerShell默认加载了GAC中旧版本的Dac.dll,即使你以为用了最新版,仍会出现超时问题。
操作步骤:
- 找到最新
sqlpackage.exe的安装目录(通常在C:\Program Files\Microsoft SQL Server\160\DAC\bin\,对应SQL Server 2022版本) - 在PowerShell中先加载该目录下的Dac.dll,再执行部署逻辑:
# 指定最新Dac.dll路径 $dacDllPath = "C:\Program Files\Microsoft SQL Server\160\DAC\bin\Microsoft.SqlServer.Dac.dll" Add-Type -Path $dacDllPath # 初始化部署选项 $deployoptions = New-Object Microsoft.SqlServer.Dac.DacDeployOptions # 设置命令超时(单位:秒,600=10分钟) $deployoptions.CommandTimeout = 600 # LongRunningCommandTimeout是16.x版本新增属性,仅在对应Dac.dll中可用 $deployoptions.LongRunningCommandTimeout = 0
2. 修正CommandTimeout的单位误解
DacDeployOptions.CommandTimeout的单位是秒,而非毫秒。若之前设置60000,实际是60000秒(约16.7小时),不符合预期且可能因底层逻辑未生效。建议设置合理值(如600秒)。
3. 补充设置连接字符串的连接超时
除了部署选项的命令超时,还需确保数据库连接字符串中包含足够长的连接超时时间:
$connectionString = "Server=YourServerName;Database=TargetDB;Integrated Security=True;Connect Timeout=300"
Connect Timeout单位同样是秒,300即5分钟,可根据实际部署时长调整。
4. 直接调用sqlpackage.exe替代Dac.dll
既然最新版sqlpackage.exe已修复超时问题,可在PowerShell中直接调用其命令行,绕过Dac.dll的版本兼容问题:
& "C:\Program Files\Microsoft SQL Server\160\DAC\bin\sqlpackage.exe" ` /Action:Publish ` /SourceFile:"C:\path\to\your.dacpac" ` /TargetConnectionString:"Server=YourServerName;Database=TargetDB;Integrated Security=True" ` /p:CommandTimeout=600 ` /p:LongRunningCommandTimeout=0
为什么LongRunningCommandTimeout不存在?
该属性是**DacFx 16.x(对应SQL Server 2022)**版本新增的配置项,旧版本(如15.x及以下)的Microsoft.SqlServer.Dac.dll中无此属性,因此会报错。必须加载对应版本的Dac.dll才能使用。
内容的提问来源于stack exchange,提问作者Murali Dhar Darshan

