9

我的数据库有表、视图等等。而且我需要一种自动为所有 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 脚本编写器的帖子,所以我想肯定有一些我错过的东西。或者......所有这些帖子都错过了这个问题吗?

4

4 回答 4

6

在编写对象脚本之前,您需要在 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

于 2013-10-23T19:34:57.273 回答
5
  1. 编写没有外键的所有表,然后只编写外键。您可以通过使用脚本选项来做到这一点,这样由于 FK 导致的表之间的依赖关系就无关紧要了。
  2. 使用DependencyWalker SMO 对象。您可以将视图的 URN 添加到其中,然后要求提供依赖关系的线性列表。我在这里对类似问题的回答包含如何使用它的示例。
于 2013-10-26T18:27:35.487 回答
1

您可以采用不同的方法并编写表格,然后编写视图。通常按照这个顺序,事情会起作用,但不是 100%。

我会将 WithDependencies 设置为 false

于 2013-10-19T13:47:24.697 回答
1

诚然,这是一种 hack,但您可以在运行脚本之前通过添加错误处理来修补脚本。您可能可以利用 V3 中的新解析器来自动执行此操作。

于 2013-10-21T12:51:02.190 回答