为何.Script与.EnumScript不支持ScriptingOptions参数?如何控制SMO脚本生成?
如何控制SMO脚本生成功能生成SQL脚本的方式?
背景
正在处理技术债务项目,负责修订团队的构建流程,目标是通过构建过程生成的脚本将本地数据库的变更部署到开发数据库。调研现有流程的替代方案时,看到过用PowerShell结合SMO的Get-SqlDatabase cmdlet获取表集合,调用.Script(ScriptingOptions)生成SQL脚本的写法。
问题
运行以下脚本时出现重载错误:
$Database = Get-SqlDatabase -Name "MyRadDatabase" -ServerInstance "(local)\MyLocalDb" $Options = New-Object -TypeName Microsoft.SqlServer.Management.Smo.ScriptingOptions # 为排查暂未设置任何选项 $Database.Tables.Script($Options)
错误信息:
Cannot find an overload for "Script" and the argument count: "1". At line:4 char:1 + $Database.Tables.Script($Options) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodException + FullyQualifiedErrorId : MethodCountCouldNotFindBest
已尝试的操作:
- 设置过一组有效的
ScriptingOptions选项 - 调用
EnumScript替代Script方法 - 创建
Scripter对象,其.Script方法可正常传入选项
注意到官方文档存在错误:比如TableCollection文档未标注Script或EnumScript方法,但实际可调用无参数的$Database.Tables.Script();且通常Script和EnumScript应该有接受ScriptingOptions的重载,但实际调用失败。
解决方案
要控制SMO脚本生成的行为,正确的做法是使用**Scripter对象**来配置选项并执行脚本生成——集合对象(如TableCollection)的Script方法确实没有接受ScriptingOptions的重载,这是文档描述的疏漏。
方法1:使用Scripter对象批量生成脚本
这是处理对象集合的推荐方式:
# 获取目标数据库 $Database = Get-SqlDatabase -Name "MyRadDatabase" -ServerInstance "(local)\MyLocalDb" # 初始化Scripter并关联数据库所在的服务器 $Scripter = New-Object Microsoft.SqlServer.Management.Smo.Scripter($Database.Parent) # 配置脚本生成选项 $Scripter.Options.ScriptDrops = $false # 不生成删除脚本 $Scripter.Options.WithDependencies = $true # 包含依赖对象 $Scripter.Options.IncludeHeaders = $true # 包含脚本头部信息 $Scripter.Options.SchemaQualify = $true # 生成带架构名的对象引用 $Scripter.Options.ScriptData = $true # 同时生成数据脚本(按需开启) # 生成所有表的脚本 $tableScripts = $Scripter.Script($Database.Tables) # 将脚本保存到文件 $tableScripts | Out-File -Path ".\GeneratedTablesScript.sql" -Encoding UTF8
方法2:针对单个对象使用带参数的Script方法
如果只需要为单个表生成脚本,单个Table对象的Script(ScriptingOptions)重载是可用的:
$Database = Get-SqlDatabase -Name "MyRadDatabase" -ServerInstance "(local)\MyLocalDb" $Options = New-Object Microsoft.SqlServer.Management.Smo.ScriptingOptions # 配置单个对象的脚本选项 $Options.ScriptData = $true $Options.ScriptSchema = $true # 生成指定表的脚本 $singleTableScript = $Database.Tables["MyTargetTable"].Script($Options)
内容的提问来源于stack exchange,提问作者Andrew Gray
相关产品推荐
相关产品推荐

