Help us understand the problem. What is going on with this article?

カレントディレクトリの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キーを押してください"
}
ssrk
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away