2006年08月18日

はじめてのSQL CLR

 SQL Server 2005のフルテキスト検索は微妙に使えない。たとえば、カスタムのトークナイザを使うにはどうすればいいのかわからない。そんなわけで、SQL CLRを使ってLucene.Netを組み込んでみた。
 同じことに挑戦する人が、たぶん日本中に10人はいると思うので、アドバイスを残しておく。
・SQL CLRの実行権限はセーフでは無理だ。Lucene.Netが同期を使っている。同期はセーフ権限ではできない。
・UPDATE文の.WRITE句は、ファイルの操作からは想像できないようなセマンティクスを持っている。ABCDEFというバイト列のBCを書き換えるとき、ファイルの操作では、AxxDEFという具合にしか変更できない。つまり、書き換え部分の長さは変更できず、書き換え部分の後の位置をずらすことはできない。しかし、UPDATE文の.WRITE句ならできる。AxxxxDEFという具合に書き換えられてしまう。私はこのセマンティクスを想像できず、糞のようにハマった。
・CJKAnalyzerの移植に挑戦したものの、どうしても解明できなかった不明な理由により、正しく動作させられなかった。
 また、SQL CLRについての雑感を。
 ストアドプロシージャというもの自体これが初体験だったが、なんとも不細工なものだという印象を受けた。DBサーバとアプリケーションサーバというレイヤ分割については、今はおいておこう。SQLのレベルのことで疑問がある。
 その1。私は十分調べたと思うのだが、ついにわからなかった――ストアドプロシージャが複数カラムのテーブル値を返すとき、その戻り値をクライアントに返さずに使うには、どうすればいいのか? SELECT hoge FROM (EXEC bar) WHERE foo = @hugaという具合に書きたいのに、どうやらできそうにない。また、戻り値を一時テーブルに放り込む方法も探したが、わからなかった。
 その2。ストアドプロシージャの戻り値の型が動的に決定される。猛烈に気持ちが悪い。この仕様を決めた奴は、悲観ロックをRDBMSに導入した奴と二つに重ねて四つに斬ってやりたい。
 以上は不細工な点だが、予想を裏切って美しかった点をひとつ。ユーザ関数に非破壊性を強制している。参照透明性の有無も設定できる。

Posted by hajime at 2006年08月18日 22:45
Comments

> 戻り値を一時テーブルに放り込む方法

これでどうですか。
(ストアドはFrom句に書けません。困りものです)

create table #temp(
attribute_id int,
attribute_name varchar(255),
attribute_value varchar(255)
)

insert into #temp
exec sp_server_info

select attribute_name from #temp
where attribute_id=10

drop table #temp

Posted by: hir at 2006年08月24日 14:37

そうですね。この構文が出てきませんでした。ありがとうございます。

Posted by: 中里一 at 2006年08月24日 22:52