クエリーしてみる

それではクエリーしてみます。とりあえず無難なところから。

select * from tbl1

これはエラーになります。

An error occurred while executing batch. Error message is: オブジェクト参照がオブジェクト インスタンスに設定されていません。

(結果をテキストで表示するモードでは)空間列が結果列に含まれてるとエラーになります。エラーメッセージはちょっと愛想ないですね。

結果を文字列形式で返すようにしてやれば問題ないので、こんな感じに変えてみます*1

select tbl1.pkey, tbl1.name, geog.STAsText() 'geog' ,geom.STAsText() 'geom' from tbl1

結果は、

pkey  name          geog                                                geom
----- ------------- --------------------------------------------------- --------------------------------------------------
100   Harry Ord     POINT (35 135)                                      POINT (35 135)
101   Kihel Heim    POINT (35 135)                                      POINT (35 135)
103   Liry Borjarno POLYGON ((35 135, 35 136, 36 136, 36 135, 35 135))  POLYGON ((35 135, 35 136, 36 136, 36 135, 35 135))
104   Sochie Heim   POINT (35 135)                                      POLYGON ((35 135, 36 135, 36 136, 35 136, 35 135))
105   Rolan Cehack  NULL                                                NULL

VPCMCE(sa): (5 row(s) affected)

こんな感じ。列数が多いテーブルだと正直マンドクセ*2

緯度経度とかSRIDを単独で取り出すこともできるので、ユーザープログラムでWKTをパースするようなプログラムを書く必要はないでしょう。

select pkey, name, geog.long, geog.lat, geom.STsrid from tbl1

...なんですが、この書き方だとエラーです。

VPCMCE(sa): Msg 6592, Level 16, State 3, Line 1
Could not find property or field 'long' for type 'Microsoft.SqlServer.Types.SqlGeography' in assembly 'Microsoft.SqlServer.Types'.

空間型に対する関数は Case Sensitive なのです。正しくは、

select pkey, name, geog.Long, geog.Lat, geom.STSrid from tbl1

結果は、

pkey        name                                                               
----------- -------------------- ---------------------- ---------------------- -----------
100         Harry Ord            135                    35                     4326
101         Kihel Heim           135                    35                     4301
103         Liry Borjarno        NULL                   NULL                   4326
104         Sochie Heim          135                    35                     4326
105         Rolan Cehack         NULL                   NULL                   NULL

VPCMCE(sa): (5 row(s) affected)

リリーボルジャーノの行はPOLYGONなので緯度経度NULLになってます。ロランセアックの行はNULLなのでSRIDもNULLです。どちらもクエリ自体がエラーになったりはしません。

面積を計ったりもできます。

select pkey, name, geog.STArea(), geom.STArea() from tbl1

事前の情報どおり、Geographyは平方メートル単位、Geometryは入力の単位(緯度経度単位)で計算されてます。

pkey        name                                        
----------- -------------------- ---------------------- ----------------------
100         Harry Ord            0                      0
101         Kihel Heim           0                      0
103         Liry Borjarno        10066273761.4702       1
104         Sochie Heim          0                      1
105         Rolan Cehack         NULL                   NULL

VPCMCE(sa): (5 row(s) affected)

単にGPS座標をテーブルに放り込んだりするだけのために空間型を使いたいという場合はここまでの説明でとりあえず事足りると思います。

続く...

*1:SQL Server 2008 では Management StudioのQueryウインドウでインテリセンスが利くようになり大変便利なのですが、空間データ型に関してはインテリセンス効きません(涙)。そのうえ geom.STAsText() のような書き方すると、構文エラーを示す赤波下線を引かれて怒られてしまいます(涙涙)。エラーを無視してExecuteすれば結果オーライなんですが。

*2:列数が多いテーブルに不用意に空間データ型を追加すると、空間データ以外の列にしか関係ない人がちょっとしたテストクエリを列指定*書いたりするとエラー発生して、空間列以外の列を全部列リストに列挙しないといけない羽目になります。空間列はできるだけ属性と別テーブルにするのも手かも。