無駄と文化

実用的ブログ

ベンダー毎の SQL の相互変換を SQL::Translator で

先日の業務中に MySQL 用に書かれた SQL ファイルを SQLServer に読ませる必要が出てきました。

『こんなの絶対誰かがもうコンバーター作ってるでしょ!』と思って探したんですが、これが意外と無かったんですよね。
唯一、見つけられた SQL::Translator を紹介します。


CLI で使える SQL::Translator

もともと SQL::Translator は perl で書かれた SQL 構文解析器モジュール、らしいです。
本来なら use SQL::Translator; で読み込んで perl スクリプトの中で使うものみたいですね。

しかし、自分は perl は書かないし、そもそもの目的が MySQL 用に書かれたSQLファイルをSQLServerに読ませる というただそれだけです。
「難しいことは言わない、コレをSQLServerで読めるように書き換えてくれ」というだけの要望なのでスクリプトは書きたくありませんでした。


しかし、なんと気の利いたことに SQL::Translator は単体のコマンドとしてコンソールから使えるようになっています。

$ sqlt -f MySQL -t SQLServer before.sql > after.sql

こんな風に。

そうだよ、コレこそが俺の求めていたものなんだよ。


インストール

perl のモジュールなので CPAN からインストールすることも出来ます。
が、CPAN からインストールしようとすると依存モジュールの解決などをユーザー側で責任持たないといけないと聞いたし、厄介だなーと思ってました。

んで、正直 perl には近寄りたくないんだよねー、と思いながらインターネット空間をスイスイしていたら、「perl のモジュールの多くが apt のパッケージとしても配布されている」という旨の情報をみつけました。
これなら依存関係の解決は apt におまかせできますね。


apt でインストール

Ubuntu などのユーザーさんは、以下のコマンドで、

$ aptitude install libsql-translator-perl

libsql-translator-perl というパッケージ名で配布されているようです。


yum でインストール

CentOS などのユーザーさんは、以下のコマンドで、

$ yum install perl-SQL-Translator.noarch

こちらは perl-SQL-Translator.noarch というパッケージ名ですなぁ。


Windows, Mac でインストール

Chocolatey や Homebrew でもインストールできる気がするんですが、そこまで調べられていません。
誰か教えてください。


使い方

インストールが済むと sqlt というコマンドが使えるようになります。
基本的な使い方しか知らないんですが、

$ sqlt -f [変換元のベンダー] -t [変換先のベンダー] [変換するSQLファイル]

てな感じで変換できます。

このままだと標準出力に結果が出て終わるので、結果をファイルに保存する場合は

$ sqlt -f [変換元のベンダー] -t [変換先のベンダー] [変換するSQLファイル] > [変換後のSQLファイルのファイル名]

という具合にリダイレクトしてあげてください。


要注意ポイント

別にバッシングしたい訳でもないんですが、使ってみて以下のポイントがイマイチだなーと感じました。

  1. SQL パースエラーの表示が雑
  2. INSERT 文を変換してくれない
  3. データ型を変換してくれない


1. について、
文法的に間違いのある SQL とかを読ませると当たり前にparse errorになるんですが、エラーメッセージとして「n行目らへんが何か変」としか言ってくれなくて不親切だなーと思いました。

まぁ、元の SQL をちゃんと書けっつー話なんですが、今回は人からもらった SQL を仕方なく変換掛けてたんで「もうちょい具体的に頼む」と言いたくなる感じでした。


2. について、
INSERT 文は丸っと無視されます。変換後の SQL を見てもごっそり消されてました。

まぁ、INSERT 文はベンダー毎の方言がほぼ無いみたいだけどサ。識別子のエスケープに使うのがダブルクォート" だったり、バッククォート` だったり、ブラケット[] だったりするみたいだしサ。そういうのの変換を君にお願いしたかったんだよネ。はぁ...。


3. について、
例えば、「MySQL にはMEDIUMINT があるけど、SQLServer には無いので代わりに INT にしなければいけない」というような型の読み替えは自動ではやってくれないようです。


まとめ

そんなわけで、
不満が残る点もありましたが、手早く変換かましたいだけの目的ならば充分に実用的だと感じました。
上記のイマイチポイントについても、変換後の SQL を実際に DB に食わせてみて、エラーや警告を手直しするくらいでなんとかなりましたしね。


私からは以上です。