2012-10-18 90 views
1

對於我的工作,我經常必須使用Microsoft SQL 2008服務器編寫包含其所有鍵,約束和觸發器(基本上是完整腳本以重新創建表)的表。爲程序和觸發器執行此操作。 我現在所做的是打開SSMS,右鍵單擊對象並選擇腳本並選擇將其編寫爲文件。所以如果我有3個程序要做,10個表格和1個觸發器,我最終會做14次。 我想要的是一個PowerShell腳本,我可以提供一個對象列表,然後它會去並使用SMO將每個腳本輸出到單個文件。使用SMO從SQL中爲單個對象編寫腳本

感謝您的幫助

回答

8

這是我每次使用腳本數據庫時都會使用的PowerShell函數。只需修改所需對象的腳本應該很容易。

function SQL-Script-Database 
{ 
    <# 
    .SYNOPSIS 
    Script all database objects for the given database. 

    .DESCRIPTION 
    This function scripts all database objects (i.e.: tables, views, stored 
    procedures, and user defined functions) for the specified database on the 
    the given server\instance. It creates a subdirectory per object type under 
    the path specified. 

    .PARAMETER savePath 
    The root path where to save object definitions. 

    .PARAMETER database 
    The database to script (default = $global:DatabaseName) 

    .PARAMETER DatabaseServer 
    The database server to be used (default: $global:DatabaseServer). 

    .PARAMETER InstanceName 
    The instance name to be used (default: $global:InstanceName). 

    .EXAMPLE 
    SQL-Script-Database c:\temp AOIDB 
    #> 

    param (
     [parameter(Mandatory = $true)][string] $savePath, 
     [parameter(Mandatory = $false)][string] $database = $global:DatabaseName, 
     [parameter(Mandatory = $false)][string] $DatabaseServer = $global:DatabaseServer, 
     [parameter(Mandatory = $false)][string] $InstanceName = $global:InstanceName 
    ) 

    try 
    { 
     if (!$DatabaseServer -or !$InstanceName) 
      { throw "`$DatabaseServer or `$InstanceName variable is not properly initialized" } 

     $ServerInstance = SQL-Get-Server-Instance $DatabaseServer $InstanceName 

     [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null 

     $s = New-Object Microsoft.SqlServer.Management.Smo.Server($ServerInstance) 
     $db = $s.databases[$database] 

     $objects = $db.Tables 
     $objects += $db.Views 
     $objects += $db.StoredProcedures 
     $objects += $db.UserDefinedFunctions 

     $scripter = New-Object ('Microsoft.SqlServer.Management.Smo.Scripter') ($s) 

     $scripter.Options.AnsiFile = $true 
     $scripter.Options.IncludeHeaders = $false 
     $scripter.Options.ScriptOwner = $false 
     $scripter.Options.AppendToFile = $false 
     $scripter.Options.AllowSystemobjects = $false 
     $scripter.Options.ScriptDrops = $false 
     $scripter.Options.WithDependencies = $false 
     $scripter.Options.SchemaQualify = $false 
     $scripter.Options.SchemaQualifyForeignKeysReferences = $false 
     $scripter.Options.ScriptBatchTerminator = $false 

     $scripter.Options.Indexes = $true 
     $scripter.Options.ClusteredIndexes = $true 
     $scripter.Options.NonClusteredIndexes = $true 
     $scripter.Options.NoCollation = $true 

     $scripter.Options.DriAll = $true 
     $scripter.Options.DriIncludeSystemNames = $false 

     $scripter.Options.ToFileOnly = $true 
     $scripter.Options.Permissions = $true 

     foreach ($o in $objects | where {!($_.IsSystemObject)}) 
     { 
      $typeFolder=$o.GetType().Name 

      if (!(Test-Path -Path "$savepath\$typeFolder")) 
       { New-Item -Type Directory -name "$typeFolder"-path "$savePath" | Out-Null } 

      $file = $o -replace "\[|\]" 
      $file = $file.Replace("dbo.", "") 

      $scripter.Options.FileName = "$savePath\$typeFolder\$file.sql" 
      $scripter.Script($o) 
     } 
    } 

    catch 
    { 
     Util-Log-Error "`t`t$($MyInvocation.InvocationName): $_" 
    } 
} 
+0

我嘗試過了,它的工作原理,但如何將我指定只有一個表或如腳本出來PROC1,表2,proc4,表6。我是對象的列表新到smo所以不知道它是如何工作的 – justinf

+0

所有要編寫腳本的對象首先收集到$ objects列表中。您可以在foreach之前過濾該列表,只保留所需的對象。 –

+0

得到這個工作謝謝! – justinf

相關問題