あらまし
現在、OracleからSqlServerへの移行案件をしている。
が、何分古すぎるシステムであること、OracleとSqlServerで一部データ型に互換性がないことから
テーブル定義の精査も含めて割と原始的な手順で移行することになった。
で、その上でのTipsの個人用メモ。
データの取得
テーブルの型
型が違う。いろんなところで微妙に違う。
varchar2とnvarcharとか(10/27削除)、dateTimeとdateとtimeとか。
(10/27追記ここから)
varchar2とnvarchar2は同じようなものだけどここで対比するものではなかった。
varchar2は「varchar」or「nvarchar」に置き換えられる。
n付はUnicode、nなしは非Unicodeな模様。
このn付はchar、text型にも言える。
どれを選べばいいかというと後述のセクション「文字化け」参照。
ORACLE | SQLServer |
---|---|
char | char / nchar |
varchar2 | varchar / nvarchar |
number | numeric / decimal※ |
date | datetime |
(以降確認次第追加予定) |
※decimalとnumericは同一。
(10/27追記ここまで)
手法としてはSI Object Browserのメニュー[スクリプト出力]を実施し、
出てきたファイルを機械的に置き換える。
定義がそもそも妥当かはすべて、データ移行後に手を付けるためここではノータッチ。
PK、FK、Indexなんかはここで付属してもいい。
ビュー、ストアド、シーケンス、トリガー等
基本的にテーブルと同じ。
が、たぶんいろいろとコンパイル通らないのでそれは都度やるしか。
文字化け(10/27追記)
2バイト文字を挿入。盛大に化けた。(SQL Server Expressにて)
オチとしてはInsert文の文字列の文字コードとDB側の文字コードの不一致の模様。
というわけでDBカラムの型がnVarcharのフィールドに入れるSQLにはプリフィックスで
「N」をつけることで回避。
本家SQLServerなら文字コードの設定で回避できるかも。
データ
こっちも[スクリプト出力]を実施してできたものを機械的に置き換える。
日付型を入れるための文字列→日付返還なんかは正規表現による置換を実施。
サクラエディタなんかでは変数を扱えるのでCtrl+Rで呼び出した置換用ダイアログで以下のように入力。
置換前:to_date\(('\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}'), 'yyyy/MM/dd hh24:mi:ss'\)
置換後:$1
これで
to_date\(('2001/04/12 12/04/31'), 'yyyy/MM/dd hh24:mi:ss'\)
とかいうのは
'2001/04/12 12/04/31'
になるのでそのままさっくり入ってくれる。
同じ要領でSysdateとかあったらそういうのを適宜対応したメソッドに置き換えていく。
データの登録
SQLCMD
OracleにとってのSQLPLUS。
接続記述
Windows認証
>sqlcmd -E -S [ホスト] -d [データベース名称]
SQLServer認証
>sqlcmd -U <user> -P [パスワード] -S [ホスト] -d [データベース名称]
とりあえずローカルで開発してるのでWindows認証でサクッと。
→つながらねぇ。
というわけで、実際につながった例のコマンドがこちら。
>sqlcmd -E -S localhost\SQLExpress -d testServer1
\SQLExpressが何で必要なんや、と思ったら
どうもインスタンス名まで指定しないとだめらしい。そりゃそうか。
SQL実行
普通にCreate table文なりSelect文を打ってチェック。
レスポンスが来ない。何故だ。
これはもう固定書式で必ず終了時に >go
がいる模様。
セミコロンでは終わってくれない。
なのでSelect文も以下のように書く必要がある。
>Select * from tblTest;
>go
これで"tblTest"から全レコードを取得できる。
ちなみに大量のInsert文発行時などは、複数分を投げた後に最後に >go
するとまとめて走ってくれる。
便利かは知らない。
ファイルの読み込み
上記で大量発生した
>:r [ファイルパス]
絶対、相対ともに可能。例のごとく >go
が必要。
ファイルの中に記述してれば実行してくれる。バッチで一括処理を考えるならあんまりおすすめしない。
で
これらを組み合わせたバッチを作れば、中身のファイルがしっかりしてればバッチ一個で
ちゃんとデータがOracleからSQLServerへ流れてくれる。
んじゃないかな。