SMO数据库脚本USE DATABASE语句

时间:2019-06-11 17:06:54

标签: powershell scripting smo

我正在尝试通过将PowerShell与SMO一起使用来生成数据库脚本。我将全部生成到一个.sql文件中。除了USE DATABASE语句,我似乎能够获得所有内容。 CREATE DATABASE部分在其上面具有USE MASTER。脚本化的其他对象(例如表和存储的proc)在其上方没有脚本化的USE DATABASE,因此可以在MASTER数据库中创建它们。

我尝试遍历所有脚本选项,但似乎没有一个在CREATE TABLE语句之前添加USE DATABASE语句。我已经尝试了各种脚本选项组合,但是没有任何东西可以提供所需的输出。

我正在寻找原因,为什么它不生成USE DATABASE语句。 在此先感谢您的任何帮助。

这是我正在使用的整个PowerShell脚本。我最初是从Internet上的某个地方获得的,并对它进行了修改。甚至原始脚本也没有在表脚本之前输出USE DATABASE语句。

    function Invoke-ScriptSqlDatabase {
[CmdletBinding()]
param(
    #SqlInstance - Source SQL Server instance.
    [Parameter(Mandatory = $true)]
    [string]$SqlInstance,
    #Database, or array of databases, to script.
    [Parameter(Mandatory = $true)]
    [array]$Database,
    #SqlAuthentication - Boolean.  Default is false (use Windows Authentication)
    [Parameter(Mandatory = $false)]
    [boolean]$SqlAuthentication,
    #Directory - This is where the script will reside.
    [Parameter(Mandatory = $true)]
    [string]$Directory,
    #ContinueScriptingOnError - If an error is encountered while generating the script, continue if $true. 
    [Parameter(Mandatory = $false)]
    [boolean]$ContinueScriptingOnError
)

BEGIN {
    #import the SQLServer module
    if (-not(get-module -name SqlServer)) {
        if (Get-Module -ListAvailable | Where-Object { $_.Name -eq "SqlServer" }) {
            import-module "SqlServer"

        }
        else {
            throw "This function requires the SqlServer module.  
        }
    }

    #append a timestamp to the generated script files
    $DateTimestamp = $(get-date -f "yyyyMMdd-HHmmss")

    #create the output directory if not exists
    if (-not( Test-Path "$Directory\" -PathType Container)) {
        New-Item -ItemType Directory -Path $Directory
    }

    #setup connection to the Sql instance.
    $SqlSMO = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -ArgumentList $SqlInstance

    #if SqlAuthentication is true, grab user credentials
    if ($SqlAuthentication) {
        $cred = Get-Credential
        $SqlSMO.ConnectionContext.LoginSecure = $false
        $SqlSMO.ConnectionContext.set_Login($cred.UserName)
        $SqlSMO.ConnectionContext.set_SecurePassword($cred.Password)

    }
    else {
        $SqlSMO.ConnectionContext.LoginSecure = $true

    }

    #try connecting
    try { $SqlSMO.ConnectionContext.Connect() } 
    catch {
        throw "Can't connect to $SqlInstance."

    }


}

PROCESS {
    #trap errors
    Trap {
        # Handle the error
        $err = $_.Exception
        write-warning $err.Message
        while ( $err.InnerException ) {
            $err = $err.InnerException
            write-warning $err.Message
        };
        # Stop the script.
        break
    }


    #loop over the array of databases and generate scripts
    $Database | ForEach-Object {

        #Check OS.  If Linux or Windows.  Update directory.
        if($env:OS) {
        $Filename = "$($Directory)\$($_)_$($DateTimestamp).sql"
        }
        else {
        $Filename = "$($Directory)/$($_)_$($DateTimeStamp).sql"
        }

        $db = $SqlSMO.Databases[$_] 

        if (-not($db)) {
            throw "The $_ database was not found on $SqlInstance."
        }

        #Create database script options
        $databaseSCRP = New-Object Microsoft.SqlServer.Management.Smo.Scripter($SqlSmo)
        $databaseSCRP.Options.ScriptBatchTerminator = $true
        $databaseSCRP.Options.IncludeHeaders = $true
        $databaseSCRP.Options.ExtendedProperties = $true
        $databaseSCRP.Options.ToFileOnly = $true
        $databaseSCRP.Options.Filename = $Filename
        $databaseSCRP.Options.SchemaQualify = $true
        $databaseSCRP.Options.ScriptSchema = $true
        $databaseSCRP.Options.IncludeDatabaseContext = $true
        $databaseSCRP.Options.NoFileGroup = $true
        $databaseSCRP.Options.NoFileStream = $true
        $databaseSCRP.Options.Permissions = $true
        $databaseSCRP.Options.ScriptForCreateDrop = $true
        $databaseSCRP.Options.IncludeIfNotExists = $true
        $databaseSCRP.Options.DriAll = $true
        $databaseSCRP.Options.ScriptDrops = $true
        $databaseSCRP.Options.WithDependencies = $true
        $databaseSCRP.Options.EnforceScriptingOptions = $true
        $databaseSCRP.Options.Encoding = [System.Text.Encoding]::UTF8
        $databaseSCRP.Script($db)

       #Script database objects
        $transfer = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Transfer -ArgumentList $db
        $ScriptOptions = New-Object -TypeName Microsoft.SqlServer.Management.Smo.ScriptingOptions

        #setup options
        $ScriptOptions.ExtendedProperties = $true
        $ScriptOptions.DriAll = $true
        $ScriptOptions.Indexes = $true
        $ScriptOptions.Triggers = $true
        $ScriptOptions.ScriptBatchTerminator = $true
        $ScriptOptions.IncludeHeaders = $true
        $ScriptOptions.IncludeDatabaseContext = $true
        $ScriptOptions.Permissions = $true
        $ScriptOptions.Statistics = $true
        $ScriptOptions.ScriptSchema = $true
        $ScriptOptions.SchemaQualify = $true
        $ScriptOptions.ToFileOnly = $true
        $ScriptOptions.IncludeIfNotExists = $true
        $ScriptOptions.FileName = $FileName
        $ScriptOptions.AppendToFile = $true
        $ScriptOptions.Encoding = [System.Text.Encoding]::UTF8

       #Continue scripting if an error is encountered?  Errors can be seen if objects have dependencies on other objects that are no longer in place.
       if ($ContinueScriptingOnError) {
               $ScriptOptions.ContinueScriptingOnError = $true
            }

        $transfer.Options = $ScriptOptions
        $transfer.ScriptTransfer()
    }

}

END {

    write-host "Script complete.  All scripts are located in the $Directory folder."  -ForegroundColor Green
}

}}

它生成的输出是:

USE [master]
GO
/****** Object:  Database [Testing_4]    Script Date: 6/11/2019 12:34:11 PM ******/
IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = N'Testing_4')
BEGIN
CREATE DATABASE [Testing_4]
 CONTAINMENT = NONE
 ON  PRIMARY 
( NAME = N'Testing_4', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL14.SQLEXPRESS\MSSQL\DATA\Testing_4.mdf' , SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 65536KB )
 LOG ON 
( NAME = N'Testing_4_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL14.SQLEXPRESS\MSSQL\DATA\Testing_4_log.ldf' , SIZE = 8192KB , MAXSIZE = 2048GB , FILEGROWTH = 65536KB )
 COLLATE SQL_Latin1_General_CP1_CI_AS
END
GO

... removed some output to save space. I believe there should be a USE [DATABASE] statement here so that the objects to follow are generated in the correct database...

ALTER DATABASE [Testing_4] SET  READ_WRITE 
GO
/****** Object:  Table [dbo].[MorePeople]    Script Date: 6/11/2019 12:34:16 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[MorePeople]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[MorePeople](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Firstname] [nchar](20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [Lastname] [nchar](20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [Username] [nchar](20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [IsActive] [bit] NULL,
 CONSTRAINT [PK_MorePeople] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
END
GO

我用于在PowerShell中执行此功能的命令行为:

Invoke-ScriptSqlDatabase -SqlInstance localhost\sqlexpress -Database Testing_4 -SqlAuthentication $false -Directory "C:\SQLServer\CreateScriptOuts" -FileUniqueId "abc137"

我正在寻找原因,为什么它不生成USE DATABASE语句以及如何解决它。

在此先感谢您的帮助。

0 个答案:

没有答案