免责声明:我是一名完整的PowerShell新手。
我有一个PowerShell脚本,用于将大量SQL脚本编译成一个脚本,以便交付给另一个团队进行迁移。它工作得很好,将所有内容包装在事务中,如果出现任何错误,可以将整个事情卷回来,但我今天遇到了一个问题。
其中一个存储过程有几个名为
的列[FirstPart-SecondPart]
但是当我将它们复制到新文件时,它们会更改为
[FirstPart?SecondPart]
这是执行concat的行:
Get-ChildItem -path $inpath -recurse |
?{ ! $_.PSIsContainer } |
?{($_.name).contains(".sql")} |
Sort fullname |
%{ Out-File -filepath $outpath -inputobject ($commentWrapper + $newLine + "-- SCRIPT: " + $_.fullname + $newLine + $commentWrapper + $newLine + $newLine +
"PRINT N'Executing script " + $_.BaseName + "'" + $newLine + $scriptHeaderPt1 + $_.BaseName + $scriptHeaderPt2 + [System.IO.File]::ReadAllText($_.fullname) +
$newLine + "GO" + $newLine + $scriptFooter + $newLine ) -Append}
以下是整个脚本:
##SQLConcat.ps1##
function Insert-Content {
param ( [String]$Path )
process {
$( ,$_; Get-Content $Path -ea SilentlyContinue) | Out-File $Path
}
}
$newLine = "`r`n"
$inpath = [Environment]::CurrentDirectory=(Get-Location -PSProvider FileSystem).ProviderPath
$outpath = $inpath + "\SQL_PACKAGE.sql"
$commentWrapper = "-- ========================================================================================== "
###################################
$logTable = "IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[log_ScriptExecution]') AND type in (N'U'))" + $newLine +
"BEGIN" + $newLine +
" PRINT N'Creating log_ScriptExecution table.'" + $newLine +
" SET ANSI_NULLS ON" + $newLine +
" SET QUOTED_IDENTIFIER ON" + $newLine +
" SET ANSI_PADDING ON" + $newLine +
" CREATE TABLE [dbo].[log_ScriptExecution] (" + $newLine +
" [id] int IDENTITY(1, 1) NOT NULL," + $newLine +
" [script] varchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL," + $newLine +
" [messages] varchar(MAX) COLLATE SQL_Latin1_General_CP1_CI_AS NULL," + $newLine +
" [executionDate] datetime NOT NULL," + $newLine +
" [executedBy] varchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL," + $newLine +
" PRIMARY KEY CLUSTERED ([id] )" + $newLine +
" WITH ( PAD_INDEX = OFF," + $newLine +
" FILLFACTOR = 100," + $newLine +
" IGNORE_DUP_KEY = OFF," + $newLine +
" STATISTICS_NORECOMPUTE = OFF," + $newLine +
" ALLOW_ROW_LOCKS = ON," + $newLine +
" ALLOW_PAGE_LOCKS = ON," + $newLine +
" DATA_COMPRESSION = NONE )" + $newLine +
" ON [PRIMARY]" + $newLine +
" )" + $newLine +
" ON [PRIMARY];" + $newLine +
"END" + $newLine +
"GO" + $newLine
###################################
$tmpErrors = "IF EXISTS(SELECT * FROM tempdb..sysobjects WHERE ID=OBJECT_ID('tempdb..#tmpErrors'))" + $newLine +
" DROP TABLE #tmpErrors" + $newLine + "GO" + $newLine + "CREATE TABLE #tmpErrors (Error int)" + $newLine + "GO" + $newLine +
"SET XACT_ABORT ON" + $newLine +
"GO" + $newLine +
"SET TRANSACTION ISOLATION LEVEL SERIALIZABLE" + $newLine +
"GO" + $newLine +
"BEGIN TRANSACTION" + $newLine +
"GO" + $newLine
###################################
$scriptHeaderPt1 = "INSERT INTO log_ScriptExecution( script ,messages , executionDate ,executedBy)" + $newLine +
"VALUES ( '"
$scriptHeaderPt2 = "' ,'Executing Script' , GETDATE() ,SYSTEM_USER)"+ $newLine +
"GO" + $newLine
###################################
$scriptFooter = "IF @@ERROR<>0 AND @@TRANCOUNT>0" + $newLine +
"BEGIN" + $newLine +
" ROLLBACK TRANSACTION" + $newLine +
"END" + $newLine +
"GO" + $newLine +
"IF @@TRANCOUNT= 0 BEGIN INSERT INTO #tmpErrors(Error) SELECT 1 BEGIN TRANSACTION END" + $newLine +
"GO" + $newLine
###################################
$fileFooter = "IF EXISTS (SELECT * FROM #tmpErrors) ROLLBACK TRANSACTION" + $newLine +
"GO" + $newLine +
"IF @@TRANCOUNT>0 BEGIN" + $newLine +
" PRINT 'The database update succeeded.'" + $newLine +
" COMMIT TRANSACTION" + $newLine +
"END" + $newLine +
"ELSE PRINT 'The database update failed'" + $newline +
"GO" + $newLine +
"DROP TABLE #tmpErrors" + $newLine +
"GO" + $newLine
###################################
#
# Delete existing SQL_PACKAGE.sql file
#
###################################
Write-Output "Deleting existing file..."
If(Test-Path $outpath)
{
Remove-Item $outpath
}
###################################
#
# Prompt the user for the target DB
#
###################################
$dbname = Read-Host 'What is the target DB name?'
###################################
#
# Compile the script(s)
#
###################################
Write-Output "Compiling script..."
Get-ChildItem -path $inpath -recurse |
?{ ! $_.PSIsContainer } |
?{($_.name).contains(".sql")} |
Sort fullname |
%{ Out-File -filepath $outpath -inputobject ($commentWrapper + $newLine + "-- SCRIPT: " + $_.fullname + $newLine + $commentWrapper + $newLine + $newLine +
"PRINT N'Executing script " + $_.BaseName + "'" + $newLine + $scriptHeaderPt1 + $_.BaseName + $scriptHeaderPt2 + [System.IO.File]::ReadAllText($_.fullname) +
$newLine + "GO" + $newLine + $scriptFooter + $newLine ) -Append}
###################################
#
# Get rid of any USE [...] statements
#
###################################
Write-Output "Removing USE statements..."
(Get-Content $outpath) | Foreach-Object { $_ -replace 'USE \[(\w+)\]', ''} | Set-Content $outpath
###################################
#
# Add the proper USE statement and Error table check to the beginning of the file
# and the file footer to the end of it
#
###################################
Write-Output "Updating file..."
$useStatement = $newLine + "USE [" + $dbname + "]" + $newLine
$useStatement + $newLine + $logTable + $tmpErrors | Insert-Content $outpath
$fileFooter | Out-File $outpath -append
Write-Output "Finished."
##SQLConcat.ps1##