Я пытаюсь получить сценарии базы данных, созданные с помощью PowerShell с SMO.Я генерирую все в один файл .sql.Кажется, я могу получить все, кроме оператора USE DATABASE.Часть CREATE DATABASE имеет ИСПОЛЬЗОВАНИЕ MASTER над ней.На других объектах, для которых выполняется сценарий, например, таблица и хранимые процессы, над ними не используется сценарий USE DATABASE, поэтому они создаются в базе данных MASTER.
Я попытался выполнить все сценарииопции, и ни один из них, кажется, не добавляет оператор USE DATABASE перед операторами CREATE TABLE.Я испробовал все виды комбинаций параметров сценария, и ничто не дает мне нужный вывод.
Я ищу, чтобы выяснить, почему он не генерирует операторы USE DATABASE.Заранее спасибо за любую помощь в этом.
Вот весь сценарий PowerShell, который я использую.Я получил это первоначально где-то в Интернете и сделал изменения к нему.Даже оригинальный сценарий не выводил оператор 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 и как ее исправить.
Спасибозаранее за любую помощь в этом.