【MySQL】DBをOracleからMySQLへ移行する件について ~その1~
OracleとMySQLはDBの仲間
Oracleは有料、MySQLは無料
という知識だけ持っている人が
「Oracleは高いからMySQLにしようぜ」
とか言い出したため、
「そんなに簡単にいくわけないだろ!」
と思ったけど、
実際にやってみたらやっぱり
一筋縄ではいかなかった話
TimeZone(タイムゾーン)の設定
まず、TimeZoneの設定値が不正です
というエラーがでた
???? (?W????)
なんとなくJISをUTFで表示してしまったときの
文字化けに見えるので
とりあえずデータベースやテーブルなど
文字コードをUTF-8にセット
しかし解消されず
実はMySQLをWindowsで使う場合に、
OSにタイムゾーンが存在しないから
起こるエラーらしく
Oracle⇒MySQL移行とは関係ないんだけど
ためになったので記載しておく次第
MySQLの設定ファイル、my.iniの
[mysqld]項目に
default-time-zone='Asia/Tokyo'
を追記
このmy.iniの場所が曲者で
MySQLをインストールした場所
(C:\Program Files\Mysql\あたり)
の下にあったファイルにだまされたのだけど
正しくは「C:\ProgramData\MySQL\あたり」
にあるmy.iniファイルを編集する必要がある
データ型のちがい
このへんは真っ先に直面する課題
OracleのDBからDDLを出力して
MySQLでSQLを流すと
データ型がちがうものがエラーになる
今回、ほとんどは
Varchar2 ⇒ Varchar Number ⇒ int
でなんとかなったけど
ほぼほぼ同一のものはない様子
関数のちがい
このへんもスタンダードな課題
よく見かけるのが
NVL ( a , b ) で a が null なら b に置き換え
MySQLでは
Case文で対応しなければいけない
のかと思っていたけど
IfNull( a , b )
で代用できる
しかしNVL2は
Case文で対応するしかないのか…
VIEWで使われているだけだったので
ソースの書き換えだけで完了
MySQLにはシーケンス機能がない
こともあろうにJavaプログラムのなかに
セッションのカウントとして組み込まれていた
たしかにネットでサンプルを見てても
セッションIDを振るのに使われていることが
多いので自然な成り行きかもしれない
シーケンスの機能自体はファンクションで代用
DELIMITER $ CREATE FUNCTION session() RETURNS int(8) DETERMINISTIC BEGIN DECLARE value int(8); SET value = 0; SELECT id INTO value FROM session_id; UPDATE session_id SET id = (CASE WHEN value = 99999999 THEN 1 ELSE value + 1 END); RETURN value + 1; END
ただ、シーケンスの呼び出しではなく
あくまでファンクションの呼び出しなので
SQLの構文が変わる
Oracleでは空のテーブルを読み込むのに
from Dualを使うけどMySQLでは
そんな仕様はないので
SELECT SESSION_ID.SESSION FROM DUAL; ↓ select session();
と変更
実は前述の2つについては
OracleからMySQLの移行を
自動でしてくれるツールがあるらしく
おそらくそれで対応可能
便利なものがあるもんだ
しかしこのシーケンスの機能や
SQLとしてプログラムに入り込んでいる
ものはさすがに移行できないのだろう
と思う
JavaのClassファイルを逆コンパイルして
javaファイルを作りなおしたのち
Classファイルに再コンパイルして、と
その辺の話はまた別の機会に記載
長くなったので今回はここまで
続きはまた次回に