dbatools/SMO导出SQL Server schema时表顺序异常导致FK约束执行失败
直接将表集合传入Export-DbaScript时,SMO会按传入的表顺序逐张生成完整脚本(包含表自身的所有约束),不会全局处理跨表的外键依赖,因此会出现被引用表还未创建就提前生成外键约束的问题。
以下是两种基于dbatools/SMO原生能力的解决方案,不需要手动遍历表集合拼接脚本:
方案1:传入数据库对象让SMO自动处理依赖排序
SMO全局处理数据库对象时会自动按依赖关系排序所有要生成的对象,从无依赖的表开始生成,完全规避顺序问题,代码示例:
# 直接获取目标数据库对象 $db = Get-DbaDatabase -SqlInstance $serverInstance -Database $database $options = New-DbaScriptingOption $options.ContinueScriptingOnError = $false $options.DriAllConstraints = $true # 限定只导出指定schema的表相关对象 $options.IncludeSchemas = $schema $options.TypeOfObjectsToScript = @('Table', 'Index', 'Constraint') # 直接导出,SMO会自动处理所有对象的生成顺序 $db | Export-DbaScript -FilePath $schemaFile -ScriptingOptionsObject $options -EnableException
方案2:分两次导出,先建表再加外键
如果需要精确控制导出的表范围,不需要导出整个库的对象,可以分两次调用导出逻辑,完全避开依赖问题:
- 第一次导出所有表结构、主键、索引,排除外键约束
- 第二次追加导出所有外键约束,此时所有表已经完成创建,不会出现依赖不存在的问题
代码示例:
$schemaTables = Get-DbaDbTable -SqlInstance $serverInstance -Database $database -Schema $schema $options = New-DbaScriptingOption $options.ContinueScriptingOnError = $false # 第一次导出:表、主键、索引、非外键约束 $options.DriAllConstraints = $true $options.DriForeignKeys = $false $schemaTables | Export-DbaScript -FilePath $schemaFile -ScriptingOptionsObject $options -EnableException # 第二次导出:追加所有外键约束 $options.DriForeignKeys = $true $options.AppendToFile = $true $options.ScriptAlter = $true $schemaTables | Export-DbaScript -FilePath $schemaFile -ScriptingOptionsObject $options -EnableException
内容的提问来源于stack exchange,提问作者Oyvind
相关产品推荐
相关产品推荐

