30代半ばの事務職員がITエンジニアになった話

おおよそタイトルのとおり、30代半ばにしてITエンジニアのタマゴになってしまった会社員の話

【MySQL】DBをOracleからMySQLへ移行する件について ~その1~

OracleMySQLはDBの仲間
Oracleは有料、MySQLは無料
という知識だけ持っている人が


Oracleは高いからMySQLにしようぜ」
とか言い出したため、
「そんなに簡単にいくわけないだろ!」
と思ったけど、
実際にやってみたらやっぱり
一筋縄ではいかなかった話


TimeZone(タイムゾーン)の設定


まず、TimeZoneの設定値が不正です
というエラーがでた

???? (?W????)


なんとなくJISをUTFで表示してしまったときの
文字化けに見えるので
とりあえずデータベースやテーブルなど
文字コードUTF-8にセット


しかし解消されず


実はMySQLWindowsで使う場合に、
OSにタイムゾーンが存在しないから
起こるエラーらしく
OracleMySQL移行とは関係ないんだけど
ためになったので記載しておく次第


MySQLの設定ファイル、my.iniの
[mysqld]項目に

default-time-zone='Asia/Tokyo'

を追記


このmy.iniの場所が曲者で
MySQLをインストールした場所
(C:\Program Files\Mysql\あたり)
の下にあったファイルにだまされたのだけど
正しくは「C:\ProgramData\MySQL\あたり」
にあるmy.iniファイルを編集する必要がある

データ型のちがい


このへんは真っ先に直面する課題
OracleのDBからDDLを出力して
MySQLSQLを流すと
データ型がちがうものがエラーになる


今回、ほとんどは

Varchar2 ⇒ Varchar
Number ⇒ int

でなんとかなったけど
ほぼほぼ同一のものはない様子


関数のちがい


このへんもスタンダードな課題
よく見かけるのが

NVL ( a , b  )  で
a が null なら b に置き換え

MySQLでは
Case文で対応しなければいけない
のかと思っていたけど

IfNull( a , b  )  

で代用できる


しかしNVL2は
Case文で対応するしかないのか…


VIEWで使われているだけだったので
ソースの書き換えだけで完了


MySQLにはシーケンス機能がない


Oracleにあって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ファイルに再コンパイルして、と
その辺の話はまた別の機会に記載


長くなったので今回はここまで
続きはまた次回に