【バッチスクリプト/SQL Server】テーブルトランケート処理


いつもお世話になっております。
RfromLです。

今回はテーブルデータをトランケート(削除)するバッチスクリプトについてです。

1.はじめに

トランケートはデータベース上にあるテーブル内のデータを一括ですべて削除することをさしています。

SQL文でトランケートを行う書式は以下の通りとなっています。

truncate table テーブル名

テーブルのデータを削除するSQL文として「Delete」でも行えますが、条件無しでテーブル内データを全削除する際は「Truncate」を使う事が多いです。

今回はバッチスクリプトから上記トランケートのSQL文を実行する方法について説明します。
動作確認で使用するテーブル定義等は以前投稿した記事「【SQL Server】複数テーブルの件数を一括カウントするSQL」の「価格情報」テーブルをそのまま使用しています。

2.環境情報

今回の手順作成実施で使用した環境は以下のバージョンとなっています。

OSWindows11 Home 64ビット
DBMSSQL Server 2019
統合環境SQL Server Management Studio v18.10
BCP15.0.2000.5

3.使用コマンド

バッチスクリプトからテーブルデータのトランケートには「SQLCMD」を使用します。

以下、SQLCMDコマンドのヘルプ(コマンド「SQLCMD /?」の実行結果)より

Microsoft (R) SQL Server コマンド ライン ツール
バージョン 15.0.2000.5 NT
Copyright (C) 2019 Microsoft Corporation. All rights reserved.

使用法: Sqlcmd            [-U ログイン ID]          [-P パスワード]
  [-S サーバー]        [-H ホスト名]              [-E セキュリティ接続]
  [-N 暗号化接続]      [-C サーバー証明書を信頼]
  [-d データベース名の使用]  [-l ログイン タイムアウト] [-t クエリ タイムアウト]
  [-h ヘッダー]        [-s 列の区切り文字]        [-w 表示幅]
  [-a パケット サイズ] [-e 入力エコー]            [-I 識別子を引用符で区切る]
  [-c コマンド終了]    [-L[c] サーバー一覧[クリーン アウトプット]]
  [-q "コマンドライン クエリ"]          [-Q "コマンドライン クエリ" と終了]
  [-m エラー レベル]   [-V 重大度レベル]          [-W 余分なスペースを削除]
  [-u ユニコード出力]  [-r[0|1] stderr へメッセージを出力]
  [-i 入力ファイル]    [-o 出力ファイル]          [-z パスワード変更]
  [-f <codepage> | i:<codepage>[,o:<codepage>]] [-Z パスワード変更と終了]
  [-k[1|2] 制御文字の削除[置き換え]]
  [-y 可変長型の表示幅]
  [-Y 固定長型の表示幅]
  [-p[1] 統計情報の出力[コロン区切り形式]]
  [-R クライアントの地域設定を使用]
  [-K アプリケーション インテント]
  [- M マルチサブネット フェールオーバー]
  [-b エラー時にバッチを中止]
  [-v var = "value"...][-A 専用管理者接続]
  [-X[1] コマンド、スタートアップ スクリプト、環境変数を無効化 [終了]]
  [-x 変数の代入を無効化]
  [-j 未加工エラー メッセージを印刷]
  [-g 列暗号化を有効化]
  [-G 認証に Azure Active Directory を使用]
  [-? 構文の要約を表示]

上記ヘルプより、今回は以下のオプションを使用します。

オプション内容
-Sサーバー名
-dデータベース名
-UログインID
-Pパスワード
-Q“コマンドライン クエリ” と終了
-e入力エコー
-bエラー時にバッチを中止

上記オプションを使用して今回実行するコマンドの書式例は以下のようになります。

[ コマンド例 ]

SQLCMD -S サーバー名 -d データベース名 -U ログインID -P パスワード -Q"truncate table テーブル名" -e -b >> ログファイル

SQLコマンドを実行し、-eオプションと、-bオプションで入力情報とエラー情報をログファイルに出力します。


4.作成スクリプト

4-1.コード内容

今回作成したスクリプトファイルのコード内容は以下の通りです。

[ 価格情報_TRUNCATE.bat ]

@ECHO OFF
@REM ------------------------------------------------------------
@REM 初期処理
@REM ------------------------------------------------------------
@REM 実行バッチファイルディレクトリ設定
SET CMD_PATH=%~dp0

@REM 処理ID設定(バッチファイル名)
SET BATCH_ID=%~n0

@REM ログファイルディレクトリ設定
SET LOGDIR=%CMD_PATH%\LOG

@REM ログファイル設定
SET LOGFILE=%LOGDIR%\%BATCH_ID%.%DATE:~8,2%.log

@REM ------------------------------------------------------------
@REM SQL Server ログイン情報設定
@REM ------------------------------------------------------------
SET SVR=※サーバー名
SET DB=※データベース名
SET USR=※ユーザー名
SET PWD=※パスワード

@REM ------------------------------------------------------------
@REM 処理開始メッセージ
@REM ------------------------------------------------------------
@REM 処理開始ログ
CALL :TIMEGET
ECHO %BATCH_ID% %YYYY%年%MM%月%DD%日 %HH%時%MI%分%SS%秒 処理開始
ECHO %BATCH_ID% %YYYY%年%MM%月%DD%日 %HH%時%MI%分%SS%秒 処理開始 >> %LOGFILE%

@REM ------------------------------------------------------------
@REM SQLCMD : 価格情報テーブル トランケート処理
@REM ------------------------------------------------------------
SET PROCNAME=価格情報テーブル トランケート処理

SQLCMD -S%SVR% -d %DB% -U%USR% -P%PWD% -Q"truncate table 価格情報" -e -b >> %LOGFILE%
IF NOT %ERRORLEVEL% == 0 GOTO ABEND

@REM ------------------------------------------------------------
@REM 正常終了処理
@REM ------------------------------------------------------------
:END
CALL :TIMEGET
ECHO %BATCH_ID% %YYYY%年%MM%月%DD%日 %HH%時%MI%分%SS%秒 正常終了
ECHO %BATCH_ID% %YYYY%年%MM%月%DD%日 %HH%時%MI%分%SS%秒 正常終了 >> %LOGFILE%
ECHO.>> %LOGFILE%

EXIT /B 0

@REM ------------------------------------------------------------
@REM 異常終了処理
@REM ------------------------------------------------------------
:ABEND

ECHO エラーコード:%ERRORLEVEL%
ECHO エラーコード:%ERRORLEVEL% >> %LOGFILE%

CALL :TIMEGET
ECHO %BATCH_ID% %YYYY%年%MM%月%DD%日 %HH%時%MI%分%SS%秒 異常終了
ECHO %BATCH_ID% %YYYY%年%MM%月%DD%日 %HH%時%MI%分%SS%秒 異常終了 >> %LOGFILE%
ECHO.>> %LOGFILE%

EXIT /B 9

@REM ------------------------------------------------------------
@REM 日時情報取得サブルーチン
@REM ------------------------------------------------------------
:TIMEGET

@REM システム日付取得(YYYY=年,MM=月,DD=日,WK=曜日)
SET YYYY=%DATE:~0,4%
SET MM=%DATE:~5,2%
SET DD=%DATE:~8,2%
SET WK=%DATE:~0,1%

@REM システム時刻取得(HH=時)
@REM ※HH部分(時間部分)の1文字目をチェックして
@REM   空白の場合は頭ゼロ埋めでセット
SET HHCHK=%TIME:~0,1%

IF "%HHCHK%"==" " (
  SET HH=0%TIME:~1,1%
) ELSE (
  SET HH=%TIME:~0,2%
)

@REM システム時刻取得(MI=分,SS=秒)
SET MI=%TIME:~3,2%
SET SS=%TIME:~6,2%

SET DATETIME="%YYYY%%MM%%DD%_%HH%%MI%%SS%"

※SQL Server ログイン情報設定の以下項目はマスキングしています。
・サーバー名
・データベース名
・ユーザー名
・パスワード

4-2.ディレクトリ構成

作成したバッチスクリプトを実行する際のディレクトリ構成です。

4-3.テーブルレイアウト

No項目名NULLKEY
1銘柄コードchar4NG1
2価格numeric9NG
3利回りnumeric5NG
4NAVnumeric9NG
5NAV倍率numeric5NG
6時価総額numeric9NG
7出来高numeric9NG
8基準年月日char8NG2

4-4.テーブルデータ

テストに使用するデータの内容です。

銘柄コード価格利回り1口NAVNAV倍率時価総額出来高基準年月日
29711180005.551234950.9641532105120220808
29711167005.611234950.9441075158520220809
2972993005.401232680.8146383334420220808
2972992005.401232680.8046336188520220809
29791545003.421288711.2010531041720220808
29791549003.411288711.2010558290120220809
29791536003.441288711.1910469694620220810
29891244005.171077241.152199432520220808
29891236005.211077241.152185241720220809
32266840002.965456451.2534437565920220808
32266790002.995456451.2434185788620220809
92811103006.0100.003290923920220808
92811103006.0100.003290916720220809
9282696005.8800.0071661720220808
9282694005.9000.0071461920220809
92831147000.0000.00230096720220808
92831147000.0000.002300910320220809
92841225006.1200.00473658620220808
92841232006.0900.004763621520220809
9285935006.4500.001645719420220808
9285934006.4600.001643992120220809

4-5.機能説明

①開始処理
・処理開始メッセージを以下の書式で標準出力とログファイルに出力する。
  「スクリプトID YYYY年MM月DD日 hh時mm分ss秒 処理開始」

②価格情報テーブル トランケート処理
・SQLCMDコマンドでTruncate文を実行して価格情報テーブルをトランケートする。

③ERRORLEVEL 判定処理
 ステータスが0の場合、正常終了処理を行う。
 ステータスが0以外の場合、異常終了処理を行う。

④正常終了処理
・正常終了メッセージを以下の書式で標準出力とログファイルに出力し処理を終了する。
  「スクリプトID YYYY年MM月DD日 hh時mm分ss秒 正常終了」

⑤異常終了処理
・エラーコードを標準出力とログファイルに出力する。
・異常終了メッセージを以下の書式で標準出力とログファイルに出力し処理を終了する。
  「スクリプトID YYYY年MM月DD日 hh時mm分ss秒 異常終了」


5.実行結果確認

実行結果確認は以下の3パターンで行います。

 ①正常終了確認(データ0件)
 ②正常終了確認(データ有件)
 ③異常終了確認(テーブル定義無し)

5-1.正常終了確認(データ0件)

①トランケート対象のテーブルが0件であることを確認

②バッチスクリプトを実行

③ログファイルを確認し、処理が正常終了していることを確認

④トランケート対象のテーブル内容が特に変化の無いことを確認

5-2.正常終了確認(データ有件)

①トランケート対象のテーブルに1件以上データがあることを確認

②バッチスクリプトを実行

③ログファイルを確認し、処理が正常終了していることを確認

④トランケート対象のテーブルの内容が0件になっている(トランケートされている)ことを確認

5-3.異常終了確認(テーブル定義無し)

①トランケート対象のテーブルが存在しないことを確認
事前にSQL文「DROP TABLE 価格情報」を実行し、テーブルドロップしておきます。

テーブルドロップ後、価格情報テーブルをselectしてテーブルが存在しないことを確認

②バッチスクリプトを実行

③ログファイルを確認し、処理が異常終了していることを確認

6.おわりに

テーブルトランケートはデータを全部削除するので、実行前にデータをエクスポートしてエクスポートしたファイルをバックアップの為に取っておくようにしておくとよいです。

以下①~③をひとつのトランケートバッチスクリプトとしてバックアップ処理を組み込んでおくのもいいかもしれません。

①エクスポートファイル名に日付情報をつけてテーブルをエクスポート
②エクスポートファイルをzipなどで圧縮
③テーブルトランケート

自宅環境など個人の場合は良いですが、現場でトランケートを実行する時はきおつけた方が良いです。

開発環境のテーブルであっても、開発メンバーの誰が使っているか分からないのでトランケートするテーブルが他の人も使いそうなテーブルか(マスタ系のテーブルなど)、使わなそうなテーブルか(ワーク系の一時テーブルなど)。

誰か使いそうなテーブルであれば、何時から何時の間はテストで消しますよ~のアナウンスを事前にしておくと良いです。

以上です。
宜しくお願い致します。


タイトルとURLをコピーしました