SQL Server同士のデータ移行(エクスポート/インポート)に思った以上に手間取った

事の発端

  • SQL Server 2000から2016へのリプレース作業中
  • 客から「新システムに入力した一部データを旧システムに戻したい」という要望
  • SQL Server 2016から一部のデータを取り出してSQL Server 2000に入れることに

旧から新にデータ移行したことはあったけど、新から旧ってなかなかなくない...?

まぁ今回はそれに関係なく「SQL Serverのデータ移行がクソ面倒だった」というお話だけど。

 

 

こんなに大変だとは思わなかった

新旧DBはネットワークで繋がっていないので、いったん2016からデータをファイルに出力して2000にインポートする作戦に。

とりあえずSSMSでクエリを書いて目的のデータを出力し、それをCSVファイルで保存することに。

005.png

お手軽簡単にCSVファイルをエクスポートできた。

 

取り込み失敗

2000の方でBULK INSERTを使って取り込んでみたが失敗。

どうやらNULLの扱いに失敗しているようだ。

001.png

カンマ区切りのCSVファイルに出力されてて、NULLのデータは「NULL」と文字で出力されてるのはちょっと謎。

 

データのインポートも失敗

取り込む方法を変え、「タスク」→「データのインポート」機能を使ってみたがこっちもダメ。

002.png

やはりNULLの扱いに失敗しているようだ。

004.png

009.png

↑2番目のエラー一番上の「0xc02020c5」がそれ。

エラーメッセージがめっちゃ分かりにくい。

 

エクスポートもできる機能あるやん

一番初めにCSVを書き出した方法ではなく「タスク」→「データのエクスポート」機能を使って書き出してみる。

006.png

こちらはCSVではなくTXTファイルで出力される。

メニュー的にもこっちの方が本来のエクスポート機能っぽいな。

003.png

インポートはさっきと同様に「タスク」→「データのインポート」から行った。

009.png

が、やはり同じエラーが出てしまい失敗。

NULLと空文字を同じ扱いにしてくれるOracleが恋しい...。正直わざわざ区別する必要ないよね?

 

INSERT文を生成する

CSV出力はNULLの扱いが難しいことを察したので、INSERT文を出力する作戦に変更。

007.png

「タスク」→「スクリプトの生成」から対象のテーブルを選択すると、そのテーブルのデータ全てがINSERT文として出力される。

008.png

注意事項としては、「詳細設定」を開いて「データのみ」を選ばないとテーブルのCREATE文しか生成されないので注意。

011.png

↓こんな感じでINSERT文が出力される。

010.png

標準のSQL文なのでNULLの扱いもバッチリ。無事成功した。

 

データの選別は?

この「スクリプトの生成」機能はテーブル単位でしかINSERT文を生成できないので、特定のデータだけを取り出すことはできない。

どうしてMSはこんな中途半端な機能しか用意しないのか...という恨み言は置いといて。

このままじゃ大量のINSERT文が吐き出されてしまい、目的行だけを取り出すのが難しい

 

ダミーテーブルを作り、欲しいデータだけを入れる

若干無理やり感はあるけどこれが一番楽だわ。

まずデータ移行したいテーブルを右クリックして「テーブルをスクリプト化」→「新規作成」→「新しいクエリエディターウィンドウ」でCREATE文を生成する。

012.png

そしてテーブル名を「DUMMY_TABLE」とかにして実行し、全く同じ構造のダミーテーブルを作成する。

あとは

INSERT INTO DUMMY_TABLE
SELECT * FROM MOTO_TABLE
WHERE HOSHII_DATA = KORE

こんな感じで目的のデータだけをダミーテーブルに放り込む。

後は先ほどの方法と同様にINSERT文を生成し、

INSERT [dbo].[DUMMY_TABLE] ([項目A], [項目B],・・・・・・・・・

と出力されたテーブル名を本来のテーブル名に置換してやればいい。

INSERT [dbo].[MOTO_TABLE] ([項目A], [項目B],・・・・・・・・・

↑こんな感じ。

 

おわりに

今回のやり方、ダミーテーブルを作らないといけないのは面倒だけど、別テーブルに移行データが残ってくれるので分かりやすというい利点はある。

後から件数チェックしたりデータ確認をするのにSQL文が使えるのから個人的にはこっちの方がよかったりもする。

というかせめてSQL Server同士のデータ移行ぐらいはもうちょっと便利にならないかなぁ...。バージョンがここまで離れていなかったらもうちょっとすんなり動いてくれるのかな。

コメントする