2010年11月15日月曜日

SELECT * で取得されるフィールドの順序は保証されているか

最近 moug で見かけたスレッドの感想です。

SELECT * FROM ~ で取得されるフィールドの順番

moug のスレッドは半年で消えるため、かいつまんで内容を書いておくと、

Q「SELECT * で取得されるフィールドの順序は保証されているか」
A「保証するという仕様を確認できない以上、保証されていることを当てにすべきではない」

と、そんな内容でした。
上記内容には、自分も まったく異論ありません。
※ 一応 念のためお断りしておきますが、Jet SQL の話です。SQL 一般の話ではありません。

さて、正論は正論として、それとは別に、内部仕様がどうなっているのか推理してみるというマニアックな楽しみ方もアリだと思うので、ちょっと考えてみました。


たとえば Jet SQL の Order By は、下記のようにフィールド インデックス (1~) を指定することができます。

SELECT *
    FROM tblCustomers
    ORDER BY 2, 3 DESC

上の例は、msdn で公開されている (DAO や ADO のようなミドルウェアではなく) Jet SQL の公式資料をそのまま引用したものです。

Fundamental Microsoft Jet SQL for Access 2000

ここでひとつ、* のフィールド順が内部仕様で定義されていないと仮定してみましょう。
そうすると必然的に、この SQL は「n 番目のフィールドを基準に並べ替える。ただし、n 番目のフィールドがどのフィールドになるかは不定」という意味になるという推測が成り立ちます。
実際には経験則的に、既存の Jet DB エンジンはフィールドを固定順で返す実装になっていると推測されますが、実装はあくまで実装です。
Jet には Red と Blue の 2 実装が存在しますから、仮に Yellow という三つ目の実装が出現して、こいつが実行するたびにランダムなフィールド順で結果セットを返す実装だったとしても、仕様的にはまったく問題ないということになります。当然、実装 Yellow において前出の SQL 文を実行すると、毎回並び順が変わることになります。

さて、Order By でフィールドが指定されているにも関わらず、並び順が不定になることが許容される、果たしてそんな仕様を MS が策定することは有りうるのか、有り得ないのか。前提自体が正しいのか、間違っているのか。

眠れぬ夜などは、そんな妄想をふくらませてみるのも、また一興。

2010/12/04 追記:
DAO の場合は、Field オブジェクトの OrdinalPosition プロパティによって決まることが、ヘルプに載っています。
たとえば、SELECT * クエリーでフィールドが返される順序は、OrdinalPosition プロパティの現在の設定値によって決まります。

0 件のコメント:

コメントを投稿