0

免責事項: 私は完全なパワーシェル ルーキーです。

移行のために別のチームに配信するために、多数の SQL スクリプトを 1 つにコンパイルするために使用する powershell スクリプトがあります。すべてをトランザクションにラップし、エラーが発生した場合は全体をロールバックしてうまく機能しますが、今日問題が発生しました。

ストアドプロシージャの1つに、次のような名前の列がいくつかあります

[FirstPart-SecondPart]

しかし、それらを新しいファイルにコピーすると、変更されます

[FirstPart?SecondPart]

これは、連結を行う行です。

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##
4

0 に答える 0