如何使用 SMO 脚本生成 sql 脚本
Posted
技术标签:
【中文标题】如何使用 SMO 脚本生成 sql 脚本【英文标题】:How to generate sql scripts using SMO scripter 【发布时间】:2013-10-26 09:43:07 【问题描述】:我的数据库有表、视图等等。而且我需要一种自动为所有 DDL 生成 SQL 脚本的方法。不需要数据。
存在 FK 约束,因此应正确排序表创建脚本。某些视图使用另一个视图,因此视图创建脚本也必须正确排序。
从MSDN Blog 上的脚本开始,我得到了以下信息:
function Generate-SqlScript
param(
[string]$srvname,
[string]$database,
[string]$ScriptOutputFileName
)
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | out-null
$srv = New-Object ("Microsoft.SqlServer.Management.SMO.Server") ($srvname)
$allUrns = @()
$allUrns += $srv.Databases[$database].Tables | foreach $_.Urn
$allUrns += $srv.Databases[$database].Views | foreach $_.Urn
$scriptingOptions = New-Object ("Microsoft.SqlServer.Management.SMO.ScriptingOptions")
$scriptingOptions.WithDependencies = $true
$scriptingOptions.AllowSystemObjects = $false
$scriptingOptions.ToFileOnly = $true
$scriptingOptions.Permissions = $true
$scriptingOptions.FileName = "$ScriptOutputFileName"
$scripter = New-Object ("Microsoft.SqlServer.Management.SMO.Scripter") ($srv)
$scripter.Options = $scriptingOptions;
$scripter.Script($allUrns)
Generate-SqlScript .\sqlexpress <MyDbName> <FilePath>
现在的问题是,WithDependencies 选项会导致视图脚本包含它的依赖表,这些表之前已经包含在内。如果我去掉 WithDependencies 选项,生成的脚本不会反映正确的顺序。
所以最终的结果包含了所有的信息,但它是不可运行的。由于无法创建表两次,因此会引发错误。
我发现有太多关于 SMO 脚本编写器的帖子,所以我想肯定有一些我错过了。或者……所有这些帖子都忽略了这个问题吗?
【问题讨论】:
【参考方案1】:在编写对象脚本之前,您需要在 PowerShell 脚本中按依赖顺序发现表并对其进行排序。在以下博客上查看此实现: http://patlau.blogspot.com/2012/09/generate-sqlserver-scripts-with.html
这个概念在 C# 中对我来说更清晰。退房: http://sqlblog.com/blogs/ben_miller/archive/2007/10/18/scripting-tables-views-and-data-using-smo-part-3.aspx
【讨论】:
【参考方案2】:-
编写所有没有外键的表,然后只编写外键。您可以通过使用脚本选项来做到这一点,这样由于 FK 导致的表之间的依赖关系就无关紧要了。
使用DependencyWalker SMO 对象。您可以将视图的 URN 添加到其中,然后要求提供依赖关系的线性列表。我对类似问题的回答 here 包含一个如何使用它的示例。
【讨论】:
感谢您的回答。我“授予”了 Renegrin 的赏金,但你的也一样好。我希望有办法分配赏金。由于不相关的原因,我的解决方案最终变成了不同的方法。【参考方案3】:您可以采用不同的方法编写表格,然后编写视图。一般来说,按照这个顺序,一切正常,但不是 100%。
我会将 WithDependencies 设置为 false
【讨论】:
WithDependencies 做了两件事:1)它通过依赖重新排序脚本。 2)它自动包含依赖元素。如果我取出WithDependencies,我不会遇到#2 的任何问题,但我需要手写才能实现#1。这是可行的,只是想确保为想要这样做的人设定正确的期望。【参考方案4】:这无疑是一种 hack,但您可以在运行脚本之前通过添加错误处理来修补它。您可能可以利用 V3 中的新解析器来自动执行此操作。
【讨论】:
以上是关于如何使用 SMO 脚本生成 sql 脚本的主要内容,如果未能解决你的问题,请参考以下文章
ScriptingOptions sql smo 不支持脚本数据
如何设置 SMO ScriptingOptions 以保证表的精确副本?
Microsoft.SqlServer.Management.Smo - 如何将列数据类型转换为 sql 表示