事の発端
- SQL Server 2000から2016へのリプレース作業中
- 客から「新システムに入力した一部データを旧システムに戻したい」という要望
- SQL Server 2016から一部のデータを取り出してSQL Server 2000に入れることに
旧から新にデータ移行したことはあったけど、新から旧ってなかなかなくない...?
まぁ今回はそれに関係なく「SQL Serverのデータ移行がクソ面倒だった」というお話だけど。
コンピューター、プログラミング、モバイル、ガジェットなどエレクトロニクス分野を中心にネタを提供するウェブサイトです。最近は中国ネタにも注力中。かつてはHWD15向けのAndroidアプリ「HWD15 Status Notifier」を作ってたりしていました。
旧から新にデータ移行したことはあったけど、新から旧ってなかなかなくない...?
まぁ今回はそれに関係なく「SQL Serverのデータ移行がクソ面倒だった」というお話だけど。
新旧DBはネットワークで繋がっていないので、いったん2016からデータをファイルに出力して2000にインポートする作戦に。
とりあえずSSMSでクエリを書いて目的のデータを出力し、それをCSVファイルで保存することに。
お手軽簡単にCSVファイルをエクスポートできた。
2000の方でBULK INSERTを使って取り込んでみたが失敗。
どうやらNULLの扱いに失敗しているようだ。
カンマ区切りのCSVファイルに出力されてて、NULLのデータは「NULL」と文字で出力されてるのはちょっと謎。
取り込む方法を変え、「タスク」→「データのインポート」機能を使ってみたがこっちもダメ。
やはりNULLの扱いに失敗しているようだ。
↑2番目のエラー一番上の「0xc02020c5」がそれ。
エラーメッセージがめっちゃ分かりにくい。
一番初めにCSVを書き出した方法ではなく「タスク」→「データのエクスポート」機能を使って書き出してみる。
こちらはCSVではなくTXTファイルで出力される。
メニュー的にもこっちの方が本来のエクスポート機能っぽいな。
インポートはさっきと同様に「タスク」→「データのインポート」から行った。
が、やはり同じエラーが出てしまい失敗。
NULLと空文字を同じ扱いにしてくれるOracleが恋しい...。正直わざわざ区別する必要ないよね?
CSV出力はNULLの扱いが難しいことを察したので、INSERT文を出力する作戦に変更。
「タスク」→「スクリプトの生成」から対象のテーブルを選択すると、そのテーブルのデータ全てがINSERT文として出力される。
注意事項としては、「詳細設定」を開いて「データのみ」を選ばないとテーブルのCREATE文しか生成されないので注意。
↓こんな感じでINSERT文が出力される。
標準のSQL文なのでNULLの扱いもバッチリ。無事成功した。
この「スクリプトの生成」機能はテーブル単位でしかINSERT文を生成できないので、特定のデータだけを取り出すことはできない。
どうしてMSはこんな中途半端な機能しか用意しないのか...という恨み言は置いといて。
このままじゃ大量のINSERT文が吐き出されてしまい、目的行だけを取り出すのが難しい
若干無理やり感はあるけどこれが一番楽だわ。
まずデータ移行したいテーブルを右クリックして「テーブルをスクリプト化」→「新規作成」→「新しいクエリエディターウィンドウ」でCREATE文を生成する。
そしてテーブル名を「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同士のデータ移行ぐらいはもうちょっと便利にならないかなぁ...。バージョンがここまで離れていなかったらもうちょっとすんなり動いてくれるのかな。
コメントする