[SQL Server] 複数テーブルのデータを一括で CSV にインポート/エクスポートする

仕事で使う技術的なこと

データベースの複数テーブルを一括で CSV 形式でエクスポートする必要があったので、そのやり方を調べてみたのですが、なかなか見つからなかったので備忘録として残しておきます。

やりたいこと

データベースのテーブル構成は、各データベースインスタンスにテーブルがぶら下がってる感じになっています。
(↓SSMSでのイメージ)

各テーブルを1つずつエクスポートする方法は調べたら見つかったのですが、一括でバッチ処理するようなやり方がなかなかわかりませんでした。

解決方法

愚直にバッチファイルに一括処理する記述をすることで解決を図りました。

1テーブルずつCSV形式でエクスポートする方法

まず、CSV形式でのエクスポート/インポート方法ですが、以下のサイト様を参考にさせて頂きました。

【SQL Server】bcpを使用したインポートとエクスポート - 小物SEのメモ帳
テストする際にテーブルのデータを一括でインポート・エクスポートする場合の方法の一つとしてbcpを使用することがありますが、オプションやフォーマットファイル出力のやり方をよく忘れるので覚書。 フォーマットファイルについては、bcpだけでなくBULK INSERTにも使えます。 bcpはコマンドラインからの実行になるので、...

今回は上記サイト様の「bcpによる一括エクスポート」と「bcpによる一括インポート」を応用させてもらいます。

バッチ処理で複数テーブルを一括でCSV形式でエクスポートする方法

本題の複数テーブルを一括でCSV形式にエクスポートする方法ですが、以下のようなバッチを書きました。

@echo off

SET /P ANSWER="エクスポートを実行します。よろしいですか (y/n)?"
if /i {%ANSWER%}=={y} (goto :yes)
EXIT
:yes
echo 処理開始

set dbName=データベースの名前

set array_01=テーブル名1
set array_02=テーブル名2
set array_03=テーブル名3
set array_04=テーブル名4
set array_05=テーブル名5
set array_06=テーブル名6
set array_07=テーブル名7
set array_08=テーブル名8
set array_09=テーブル名9
set array_10=テーブル名10
set array_11=テーブル名11

mkdir log

for /f "usebackq delims== tokens=1,2" %%a in (`set array`) do (
    echo %dbName% dbo.%%b
    bcp dbo.%%b format nul -c -x -f .\%%b.xml -t, -S サーバー名 -U ユーサー名 -P パスワード -d %dbName%
    bcp dbo.%%b out .\%%b.csv -S サーバー名 -U ユーサー名 -P パスワード -d %dbName% -f .\%%b.xml -t, -o .\log\%%b.log
)

解説します。
まず、バッチ内の疑似配列変数にテーブル名を列挙しておきます。(Array_XX の部分)
そして、for 文で配列数だけ繰り返して「bcpによる一括エクスポート」を実行しています。
「bcpによる一括エクスポート」の内容については、参考サイト様の記事を参考にしください。

なお、バッチファイルにおける疑似配列変数の記述方法は、下記サイト様を参考にさせて頂きました。

バッチファイルで配列とforeachを使う方法 - Qiita
はじめにWindows バッチファイルには、値の集合を取り扱うためのデータ構造や文法規則はありませんが、シンボル名をうまく処理することで、配列やforeachに近い処理を行うことが出来ます。要素…

バッチ処理で複数テーブルを一括でCSV形式でインポートする方法

次にインポートですが、これはほとんどエクスポートと同じです。

下記のようなバッチ処理を書きました。

@echo off

SET /P ANSWER="インポートを実行します。よろしいですか (y/n)?"
if /i {%ANSWER%}=={y} (goto :yes)
EXIT
:yes
echo 処理開始

set dbName=データベースの名前

set array_01=テーブル名1
set array_02=テーブル名2
set array_03=テーブル名3
set array_04=テーブル名4
set array_05=テーブル名5
set array_06=テーブル名6
set array_07=テーブル名7
set array_08=テーブル名8
set array_09=テーブル名9
set array_10=テーブル名10
set array_11=テーブル名11

mkdir log

for /f "usebackq delims== tokens=1,2" %%a in (`set array`) do (
    echo %dbName% dbo.%%b
    bcp dbo.%%b format nul -c -x -f .\%%b.xml -t, -S サーバー名 -U ユーサー名 -P パスワード -d %dbName%
    bcp dbo.%%b in .\%%b.csv -S サーバー名 -U ユーサー名 -P パスワード -d %dbName% -f .\%%b.xml -t, -o .\log\%%b.log -E
)

追記:はまったこと

上記のバッチ処理にある bcp dbo.%%b in .\%%b.csv -S サーバー名 -U ユーサー名 -P パスワード -d %dbName% -f .\%%b.xml -t, -o .\log\%%b.log -E ですが、
-E オプションを付けないとうまくいかないことがありました。

また、管理者権限で実行しないとエラーになりました。
参考: https://ips.nekotype.com/4252/

まとめ

けっこうやっつけ感がありますが、今のところこのやり方以外に思いつかないです。。。

コメント

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