Rails + SQLServerでクエリがシンタックスエラーな件

$KCODE = 'u'でrailsを動かすとSQLServerへのクエリがエラーを起こすんだが。 前にメーリングリストでも見かけたことがあったような。で、$KCODE = 's'で我慢しるってことだったような。

ちょっと試してみた。

どうも、ADODBをラップしてるWin32OLEのRuby StringとBSTRの変換が問題なような感触。

require 'dbi'
require 'iconv'

$KCODE = 's'
value = 'てすと'
sql = "INSERT INTO hoge(val) VALUES('#{value}')"
usql = "INSERT INTO hoge(val) VALUES('#{Iconv.conv('UTF-8', 'CP932', value)}')"
DBI.connect(connect_string).execute(sql) # => ok
DBI.connect(connect_string).execute(usql) # => データが化ける

$KCODE = 'u'
DBI.connect(connect_string).execute(sql)
 # =>
   DBI::DatabaseError: Execute
   OLE error code:80040E14 in Microsoft OLE DB Provider for SQL Server
     文字列 ')' の前で引用符が閉じていません。
   HRESULT error code:0x80020009
     例外が発生しました。
       from /usr/lib/ruby/1.8/DBD/ADO/ADO.rb:135:in `execute'
       from /usr/lib/ruby/site_ruby/1.8/dbi.rb:888:in `execute'
       from /usr/lib/ruby/site_ruby/1.8/dbi.rb:480:in `execute'
       from (irb):66
       from :0

DBI.connect(connect_string).execute(usql) # => データが化ける

ということは、ADO.rbで使えるようなADODB.Connectionのラッパを拡張ライブラリで書いてやればいけるのか。 まぁ、そんなことしなくても、セッションに紐付いたコードページを変更してそれに合わせてサーバー側で変換させられれば良いんだけど。でも、その辺の設定がどうしてもわからない。"SET LANGUAGE = "は違うよな。

つーか、Rubyは文字列のエンコーディング周りは遅れてる。Stringが文字列といいつつ実際のところバイト列であるのが痛い。文字列オブジェクトを名乗るからには自分のエンコーディングは知っててほしいよね。エンコーディング情報が文字列オブジェクトじゃなくて$KCODEにあるせいで、エンコーディング混在が難しいわけだ。

Perl5はよーでけとるよなぁ。Encode.pmもあるし羨ましい。

Rubyも2.0ではその辺はなんとかなる予定らしいけれど、2.0リリースより先にm17nがマージされたりしないのかな。そういえばm17nはどうなってたろ。久しぶりに覗いてみよう。なんかお手伝いできそうなことがあれば...