OracleでもGIS(5)

設定をいじる前にちょっとした実験をしてみた
重複を許さない主キーが設定されているデーブルに対してOracle Enterprise Manager 10g Database ControlとSQL Plusで同じ主キーのインサート分を発行するのだ
先に発行したほうが通り、後が弾かれるか双方ともが衝突して消えるのか。実際にやってみた
まずはOracle Enterprise Manager 10g Database Controlでインサート発行。問題なくうまくいく
その後、同一のアカウントでログインしていたSQL Plusでまったく同じインサートを発行してみた

……
………止まった
エラーも何も、発行した途端にSQL Plusはフリーズした
「キャンセル」を選択した時のように、DBを抱えて沈まなかったようだが何か不具合が出たのか。この様な状態が出るなら、オートナンバー又は重複しないユニークなコード作成が必要になりそうである
Oracle Enterprise Manager 10g Database Controlで追加したデータはログアウトすると、問題なく追加されていた。ふむ…

以上の事から、複数個の同時アクセスが存在していた場合に加速度的に品質が低下する可能性が伺える。原因は恐らく確定した処理にも関わらず、主キー重複というエラーが発生する状況だったからだろう。ならばフローにその場合の回避を組み込むか、そもそも衝突しない形式がその望ましい設計だ。例えば、デフォルトのロールバックに頼るのではなく一時的なDBを用意するのはどうだろうか
ショッピングサイトを例にあげるのら注文と売上が直結しない形式が望ましいということだ
Oracleを利用するには恐らく第三正規化まで通過したDBでないと逆にデメリットになりそうだ。その分、メリットが発生した場合は安定する
オープンソースDBが有力な中、確かに有料DBの商戦として正しい形なんだろう。あれだ、マックとモスの関係
…む、例えで台無しだ。しかし、これほど言い得てる表現もないと思う

いいかげん脇道(でもないのだが)調査は取りやめて、GISについて突っ込んでいく
先ずは相変わらずおまじない構文のままのインサートで発行したジオメトリ構文の詳細だ

INSERT INTO gis_t (id,geom) VALUES (
6,
SDO_GEOMETRY(
2003,-- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,1), -- one polygon (exterior polygon ring
SDO_ORDINATE_ARRAY(5,1, 8,1, 8,6, 5,7, 5,1)
));

これが発行した構文の一例
で、このデータが格納されたカラムを引き出してみるとこう帰ってくる

SDO_GEOMETRY(2003, NULL, NULL, 
SDO_ELEM_INFO_ARRAY(1, 1003, 1), 
SDO_ORDINATE_ARRAY(5, 1, 8, 1, 8, 6, 5, 7, 5, 1))

列の名称は定義した名称ではなく、この様に帰ってきている

GEOM(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)

この形式はSpatialジオメトリオブジェクトと呼ばれる
実際にプログラムで扱う場合、情報正規化と解析処理が省けるであろう面白い形式だ
しかし、まあ意味不明。このままではこのデータがポリゴンなのか何なのか訳が分からない。ちなみに、放り込んだデータは一応ポリゴンである
一応、確認としてWKTで取り出してみる。構文は以下の通り

SELECT SDO_UTIL.TO_WKTGEOMETRY(geom) FROM gis_t;

SDO_UTIL.TO_WKTGEOMETRYはSpatialジオメトリオブジェクトをwell-known text形式に変換してくれる。バイナリで習得したいならSDO_UTIL.TO_WKBGEOMETRYだ
ちなみに、逆も存在しておりSDO_UTIL.FROM_WKBGEOMETRYがバイナリからの変換。SDO_UTIL.FROM_WKTGEOMETRYがwell-known textからの変換である
ちなみに、完全に道草だがSDO_UTIL.RECTIFY_GEOMETRYは渡されたジオメトリが向こうの場合、有効な情報に修正して返してくれる代物。やはり機能は豊富だ
元の道に戻ろう
いくら調べてもSpatialジオメトリオブジェクトの内容について分かりやすい詳細が見つからない。そもそも定義時にどのような設定が最適なのか難しい
では、関数で誤魔化してしまおう(言い方は悪いが)
さぎほど上げた関数SDO_UTIL.FROM_WKTGEOMETRYを利用する
つまりWKTをジオメトリクエリの値に定義すれば自動でDBに格納できる!WKTならポリゴンラインマーカー、各オブジェクトの定義もただのテキストで簡単だ
では、インサートを実際に組んでみよう

INSERT INTO gis_t (id,geom) VALUES (8,
SDO_UTIL.FROM_WKTGEOMETRY(('POINT((5.0 1.0, 8.0 1.0, 8.0 6.0, 5.0 7.0, 5.0 1.0))'));

こんな感じ
…実行してみるとSDO_UTIL.FROM_WKBGEOMETRYの引数が不正だと言われる
書き方が違うのか?WKTで出力したポリゴン情報でインサートを噛まして見よう。これならWKTが原因かどうか分かる

カンマがありません

…?
しかもポイントされてるのは最後尾、WKTのすぐ後ろだ
馬鹿正直に,を取り付けてみたらやっぱりエラーが出る。
「式がありません」
当然のエラーだ。むう、これが出来たらすべての問題が解決するのだが…