クールな新機能トップ10
紹介する順番はあまり気にしないでください。10個の機能を選ぶだけでもなかなか大変でした。あえてランク付けしようとは考えていません。
1. 変数へのUNLOAD
LOAD文とUNLOAD文がファイルだけでなく、変数に対しても機能するようになりました。変数を利用してファイル仕様を保存するだけでなく、変数やファイルに保存されたデータをロードしたりアンロードしたりすることが可能になりました。テーブルのすべてのローとカラムを1つの文字列変数にUNLOADしたり、逆に、文字列からテーブルをLOADしたりできます。
BEGIN DECLARE s LONG VARCHAR; UNLOAD TABLE t1 TO s; LOAD TABLE t2 FROM s; END;
ファイルの代わりに変数を使うことの利点を以下に挙げます。
- 同時性の改善。ファイルはグローバルであるのに対して、変数は接続にローカルのため、同時性が改善されます。
- 柔軟性の向上。SQL Anywhereには文字列を操作する強力な関数がたくさんありますが、ファイルを操作する関数の数はそれほど多くありません。
- 処理速度の向上。ファイル入出力が行われないため、速度が向上します。ただし、調子に乗ってINSERT SELECTの代わりにUNLOAD LOADなどとしないように注意してください。そこまで速くはなりません。
この機能はUNLOAD SELECTやUNLOAD TABLEでも有効のため、変数に保存されたデータを完全に制御するクエリを書くことができます。
個人的な話になりますが、この機能については少々複雑な思いがあります。筆者は長年にわたってこの機能を要求していたのですが、初めて使用できるようになったときには、その使い道を思いつくことができませんでした。というのも、この機能が実現するまでの間に、他の機能を利用して問題を解決できるようになってしまったからです。最も重要だったのは、拡張LIST集約関数です。LIST関数とSTRING関数をLISTのデリミターおよびORDER BY句と組み合わせて使用することで、集合指向の文字列操作を実行できます。例えば、1つのSELECTを使って、複数のテーブルをジョインし、データをフォーマット済みのHTML Webページに変換できます。
筆者はずば抜けて頭がいいとは言えません。新しい機能が使えるようになったからと言って、直ちにその使い道が分かるわけではありません。LISTの場合もそうだったし、変数へのUNLOADの場合も同じことが言えます。ただし、だれかが使い道を教えてくれれば話は違います。その場合の飲み込みは早い方です。Ivan Bowmanがこの新機能を次に紹介する機能と組み合わせる方法を教えてくれたときがそうでした。
2. FROMOPENSTRING
新しいOPENSTRING句を使うと、SELECTのFROM句でファイルまたは変数の名前を指定し、SQL Anywhereにそのファイルまたは変数の内部のデータをローとカラムの集合として処理させることができます。これはプロキシテーブルを使って、ODBCリモートアクセスミドルウェアを介してファイルをテーブルのように処理する方法に少し似ていますが、それよりずっと簡単で、柔軟性が高い方法です。それに、OPENSTRINGでは、ファイルだけでなく、変数も使えます。
この機能についても、少々ばつの悪い思い出があります。当初、筆者はこれをよくある使いにくいXMLのたぐいだと考えていました。最近は何にでも「オープン(open)」という言葉が使われすぎていて、その言葉を聞くだけでうんざりしていたのです。そこで、OPENSTRINGという機能を頭から無視して、「そのうち車にはねられた動物の死骸(corpse)のことを『OpenCorpse』とかなんとか呼ぶようになるんだろうよ」などと思っていました。
ところが、Wikipediaの「IvanAnywhere」として名高いIvan Bowmanが、OPENSTRINGを変数へのUNLOAD SELECTと組み合わせて使用する例を見せてくれたとき、私の考えは変わりました。ここで紹介しておきましょう。
「私が考えた便利な使用例は次のようなものです(ここで使用しているSYSDOMAINはただの例です)。
CREATE VARIABLE @var LONG VARCHAR; UNLOAD SELECT * FROM SYSDOMAIN INTO VARIABLE @var; CREATE VIEW V AS SELECT * FROM OPENSTRING ( VALUE @var ) WITH ( domain_id SMALLINT, domain_num VARCHAR ( 128 ), type_id SMALLINT, "precision" SMALLINT ) AS T;このコードが何をやっているかと言えば、結果セットを接続レベル変数
@var
にコピーし、ビューVを使ってその結果セットを参照しています。@var
の値は接続プロシージャで作成できます。これは、ホットデータのローカルオプションの設定や接続ローカルキャッシュを管理する(ホットなローの競合を回避する)適切な方法になり得ます。この種の機能の使い方には注意が必要ですが、これは必要なときにすぐ使える便利なツールです。ビューに対するINSTEAD OFトリガーを作成して、ビューをテーブルのように見せることもできます。
OPENSTRING機能は、INリストが文字列として指定されている動的なINリストの処理に最適と思われます。この機能を利用すれば、SQL Anywhereでは直接サポートされていないマルチカラムのINリストを使用することもできます。
OPENSTRINGをLISTと組み合わせると面白い使い道があるかもしれません。これは1つのカラム値をデコードして結果セットを得るラテラルジョインのように見えます。私は過去に何度も
sa_splitlist()
を使って面白いソリューションを構築してきましたが、いずれもOPENSTRINGで対応することができそうですし、別の要件にも利用できそうです。なぜなら、OPENSTRINGはカラムだけでなくローのデコードも行い、従来の方法よりずっと高速で、複雑なデータを処理するための解析オプションをより多く備えているからです。私は、これらの新機能が実際の現場でどのような用途に使われるのかに興味があります。」Ivan T. Bowman(アイエニウェア社エンジニア)
Ivanの最後のコメントについては、まさに同感です。新しい機能がどのように利用されていくかは簡単には予想できません。LIST関数のように直ちに受け入れられるものもあれば、ANSI標準の再帰結合のように敬遠されるものもあるでしょう。おそらくOPENSTRINGは人気の機能になるのではないでしょうか。変数へのUNLOADもそうなると思います。
Ivanは、これまでどこのトップ10リストにもランクインしていない、バージョン10.0.1でひっそりと導入されたもう1つの機能についても語っています。その機能とはINSTEAD OFトリガーです。このトリガーを利用すると、テーブルやビューに対して、トリガーアクションの代わりに実行されるトリガーを書くことができます。例えば、INSTEAD OF INSERT ON Tトリガーを用意しておくと、INSERT T文が実行されたときにこのトリガーが起動しますが、このトリガーではローの挿入を行いません。INSERT Tの結果として実行したいアクションがある場合は、このトリガーの内部にコーディングする必要があります。
この機能がクールなのは、ビューに対するトリガーを書けるという点です。ビュー自体が更新可能でない場合でも、そのビューに対するトリガーを作成できるのです。INSERT、UPDATEまたはDELETEをトリガーしても、それに対応するINSTEAD OFトリガーが存在しさえすれば、挿入、更新または削除は実行されないため、ビューが更新可能かどうかは問題になりません。また、このトリガー内には実行したいアクションを自由にコーディングできます(もちろんCOMMITをコーディングすることはできません。その制約は変わりません)。