【バッチスクリプト/SQL Server】テーブルエクスポ-ト処理

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

今回はテーブルデータをエクスポートするバッチスクリプトについてです。

1.はじめに

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

2.環境情報

実施環境は以下の通りです。

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

3.使用コマンド

テーブルデータのエクスポートにはいくつか方法がありますが、ここでは一番一般的な「BCP」コマンドの「OUT」オプションにより行います。

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

使用法: bcp {dbtable | query} {in | out | queryout | format} datafile
  [-m 最大エラー数]        [-f フォーマット ファイル]   [-e エラー ファイル]
  [-F 先頭行]              [-L 最終行]                  [-b バッチ サイズ]
  [-n ネイティブ型]        [-c 文字型]                  [-w UNICODE 文字型]
  [-N text 以外のネイティブ型を保持] [-V ファイル フォーマットのバージョン] [-q 引用符で囲まれた識別子]
  [-C コード ページ指定子] [-t フィールド ターミネータ] [-r 行ターミネータ]
  [-i 入力ファイル]        [-o 出力ファイル]            [-a パケット サイズ]
  [-S サーバー名]          [-U ユーザー名]              [-P パスワード]
  [-T 信頼関係接続]        [-v バージョン]              [-R 地域別設定有効]
  [-k NULL 値を保持]       [-E ID 値を保持][-G Azure Active Directory 認証]
  [-h "読み込みヒント"]    [-x XML フォーマット ファイルを生成]
  [-d DB 名]  [-K アプリケーション インテント]  [-l ログイン タイムアウト]


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

オプション内容
-c文字データ形式で出力
-t区切り文字の指定
-r改行コードの指定
-Sサーバー名の指定
-UユーザーIDの指定
-Pパスワードの指定


ヘルプを基に今回使用するコマンドは以下の書式を使います。



[ コマンド例 ]

BCP DB名.テーブル名 OUT 出力ファイル名 -c -t , -r \n -S サーバー名 -U ユーザー -P パスワード >> ログファイル

上記コマンドでは、区切り文字をカンマ指定、改行コードにCRLFを指定しています。
また、リダイレクトでログファイルを指定することで処理メッセージをログファイルに出力します。


4.作成スクリプト

4-1.コード内容

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


[ 価格情報_UNLOAD.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 DBアンロードファイル格納ディレクトリ
SET DBDIR=%CMD_PATH%\unload

@REM ------------------------------------------------------------
@REM SQL Server ログイン情報設定
@REM ------------------------------------------------------------
SET DB=※データベース名
SET ONR=dbo
SET SVR=※サーバー名
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 BCP : 価格情報テーブル アンロード処理
@REM ------------------------------------------------------------
SET PROCNAME=価格情報テーブル アンロード処理

set TBL=価格情報
set ULOADFILE=価格情報DMP_unload.txt

BCP %DB%.%ONR%.%TBL% OUT %DBDIR%\%ULOADFILE% -c -t , -r \n -S %SVR% -U %USR% -P %PWD% >> %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.テーブルレイアウト

項目名NULLKEY
銘柄コードchar4NG1
価格numeric18, 0NG
利回りnumeric09, 2NG
NAVnumeric12, 0NG
NAV倍率numeric09, 2NG
時価総額numeric12, 0NG
出来高numeric12, 0NG
基準年月日char8NG2

4-4.テーブルデータ

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

銘柄
コード
価格利回り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.エクスポートファイル仕様

※データ自体はテーブルデータをそのまま出力します。

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

区切り文字:,(カンマ)区切り
改行コード:CRLF
文字コード:S-JIS

4-6.機能説明

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

②価格情報テーブル アンロード処理
・BCPコマンドのOUTオプションで価格情報テーブルをエクスポートする。

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

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

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


5.実行結果確認

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

 ①正常終了確認(データ0件)
 ②正常終了確認(データ有件)
 ③異常終了確認

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

①エクスポート対象のテーブルが1件以上データがあることを確認

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

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

④エクスポート先のディレクトリに0件ファイルが作成されていることを確認
エクスポート先にファイルが作成されていることを確認します。

実際にエクスポートファイルを開いて、レコードが0件で作成されていることを確認します。

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

①エクスポート対象のテーブルが1件以上データがあることを確認

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

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

④エクスポート先のディレクトリにファイルが作成されテーブルデータが出力されていることを確認
エクスポート先にファイルが作成されていることを確認します。

実際にエクスポートファイルを開いて、テーブルデータの内容を確認します。

5-3.異常終了確認

①エクスポート対象のテーブルが0件以上データがあることを確認

②エクスポート先のディレクトリにエクスポートファイル名と同名のファイルを配置し排他設定でファイルを開いておきます。

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

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

⑤エクスポート先の開いていたファイル内にデータが出力されていないことを確認

バッチスクリプト実行前から開いていたエクスポート先ファイルを開き直して更新してもファイル内にデータが出力されていないことを確認

6.おわりに

実行結果確認より、「NAV倍率」項目のようにデータ内容が「0.96」などのように小数値項目の整数部が「0」(ゼロ)になっている項目は整数部の0が省略されて「.96」と出力されています。

この事象を回避する1例としては、対象のテーブルをselect、selectする際に該当項目を「convert(char,NAV倍率)」などで文字列に変換するビューを作成します。そして、作成したビューテーブルに対してエクスポートを行うなどの方法があります。

ほかにもエクスポートした後にエクスポートファイルに対して編集を行う処理をつくるなど方法はありますが、その時の状況や現場のルール・文化によって対応は変わってくると思います。

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


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