カレントディレクトリのSqlファイルを自動適用する


やりたいこと

実行フォルダにある、Sqlファイルをいい感じに適用するバッチがほしい。
ファイル構成は下記のようなのを想定。

【構成】
・実行ファイル(PowerShell)
・クラスファイル(PowerShell)
・01_SEL_Backup.sql
・02_UPD_Update.sql
・03_SEL_Check.sql

 スクリプト

ExecuteSqlFileCurDir.ps1
using namespace System.IO;
using namespace System.Text;

# クラスの読み込み
. (Join-Path $MyInvocation.MyCommand.Path ../Logger.ps1);        # Logクラス読み込み
. (Join-Path $MyInvocation.MyCommand.Path ../SqlManager.ps1);    # SqlServerの操作クラス読み込み

# DB接続用
[String]$strServer   = 'localhost';
[String]$strDatabase = 'TempDB';
[String]$strUserId   = 'sa';
[String]$strPassword = 'sa';

# ログクラス
[Logger]$clsLogger   = $null;

# =============================================================
# Method   : MainProcess
# -------------------------------------------------------------
# Summary  : カレントディレクトリのSqlファイルを適用
# =============================================================
Function MainProcess()
{   
    [Boolean]         $bResult     = $false;
    [FileSystemInfo[]]$aFileInfo   = $null;

    # ログクラス初期化
    $clsLogger = [Logger]::New();
    $clsLogger.Initialize();

    # 対象のSqlファイル取得
    $aFileInfo = Get-ChildItem $PSScriptRoot -File -Filter *.sql | Sort-Object

    # Sqlファイルごとにループ(昇順)
    foreach($item in $aFileInfo)
    {
        # 実行確認
        $bResult = RequestY/N("[確認]『{0}』を実行しますか?" -f $item.Name)

        if($bResult)
        {    
            # Sqlファイルの適用
            $clsLogger.WriteLog($item.Name + "を実行します。");
            ApplySqlFile($item.FullName);
        }
        else
        {
            $clsLogger.WriteLog($item.Name + "の実行をキャンセルしました。");
            continue;
        }
    } 
}

# =============================================================
# Method   : ApplySqlFile
# -------------------------------------------------------------
# Summary  : SqlファイルをDBに適用
# Param1   : Sqlファイルのパス
# Return   : Yes:true, No:false
# =============================================================
Function ApplySqlFile([String]$strFilePath)
{
    [Int32]       $iCount          = 0;
    [Boolean]     $bResult         = $false;
    [String]      $strFileName     = $null;
    [String]      $strQuery        = $null;
    [StreamReader]$clsStreamReader = $null;
    [SqlManager]  $clsSqlMng       = $null;

    try
    {
        # ファイル名取得
        $strFileName = (Get-Item $strFilePath).BaseName;

        # Sqlファイルの読み込み
        $clsStreamReader =[StreamReader]::new($strFilePath, [Encoding]::UTF8);
        $strQuery = $clsStreamReader.ReadToEnd();

        # DB接続クラス初期化(接続)
        $clsSqlMng = [SqlManager]::New($strServer,$strDatabase,$strUserId,$strPassword);

        # ファイル名称で処理分岐
        if($strFileName.Substring(3, 3) -in @("UPD", "INS", "DEL"))
        {
            # -------------------------------
            # 更新系処理
            # -------------------------------
            try
            {
                $clsSqlMng.BeginTran();
                $clsSqlMng.ExecuteQuery($strQuery) > $null;

                $bResult = RequestY/N("[確認]『{0}』をコミットしますか?" -f $item.Name)
                if($bResult)
                {
                    $clsSqlMng.Commit();
                    $clsLogger.WriteLog($strFileName + "の実行に成功しました。")
                }
                else
                {
                    $clsSqlMng.RollBack();
                  $clsLogger.WriteLog($strFileName + "の実行をキャンセルしました。");
                }   
            }
            catch
            {
                $clsLogger.WriteLog($strFileName + "の実行に失敗しました。");
                $clsLogger.WriteLog(($error[0] | Out-String))
                $clsSqlMng.RollBack();
            }
        }
        else
        {
            # -------------------------------
            # 参照処理
            # -------------------------------
            foreach($item in $clsSqlMng.Fill($strQuery))
            {
                # 結果をTSVで保存する
                $iCount++;
                $item | export-csv (Join-Path $PSScriptRoot ("{0}_{1:00}.tsv" -f $strFileName, $iCount)) -Encoding Default -Delimiter `t -NoTypeInformation;
            }
            $clsLogger.WriteLog($strFileName + "の実行に成功しました。");
        }
    }
    catch
    {
        $clsLogger.WriteLog($strFileName + "の実行に失敗しました。");
        $clsLogger.WriteLog(($error[0] | Out-String))
    }
    finally
    {
        if($clsStreamReader -ne $null)
        {
            $clsStreamReader.Close();
            $clsStreamReader = $null;
        }
        if($clsSqlMng -ne $null)
        {
            $clsSqlMng.Dispose();
            $clsSqlMng = $null;
        }
    }
}

# =============================================================
# Method   : MainProcess
# -------------------------------------------------------------
# Summary  : Yse / Noの選択肢を表示
# Param1   : 出力メッセージ
# Return   : Yes:true, No:false
# =============================================================
Function RequestY/N([String]$strMessage)
{
    [String]$strAnswer = $null;

    while($true)
    {
        $strAnswer = Read-Host ($strMessage + " [Y] Yes / [N] No")

        switch($strAnswer)
        {
            "Y" {return $true}
            "N" {return $false}
            default 
            {
                Write-Host "Y/N のどちらかを入力してください`r`n"
            }
        }
    }
}

# メイン処理の実行
MainProcess

# 終了確認メッセージ
if ($Host.Name -notmatch "ISE") 
{
  Read-Host "終了するにはEnterキーを押してください"
}