xmltype 列とその他の非 xmltype 列を持つテーブル (Oracle 11.2.0.2) があります。非 xmltype 列の値と xmltype 列の内容に基づいて選択したいと考えています。
select で xmlquery を使用してこれを実行しようとしましたが、面白い結果が得られます。これが私のデータの縮小版です。ユーザー名と注文の詳細を含む注文テーブルです。
-- create order table
create table orders(username varchar2(20), order_data xmltype);
-- an order entered by jim
insert into orders values ('jim', xmltype('
<ord:order xmlns:ord="http://www.blah.com/order/1.0">
<ord:zip>123</ord:zip>
<ord:date_time>2012-09-24T00:27:00</ord:date_time>
<ord:item>
<ord:product>A</ord:product>
<ord:quantity>12</ord:quantity>
</ord:item>
<ord:item>
<ord:product>B</ord:product>
<ord:quantity>34</ord:quantity>
</ord:item>
</ord:order>'));
-- an order entered by bob
insert into orders values ('bob', xmltype('
<ord:order xmlns:ord="http://www.blah.com/order/1.0">
<ord:zip>123</ord:zip>
<ord:date_time>2012-09-24T00:27:00</ord:date_time>
<ord:item>
<ord:product>A</ord:product>
<ord:quantity>56</ord:quantity>
</ord:item>
<ord:item>
<ord:product>C</ord:product>
<ord:quantity>78</ord:quantity>
</ord:item>
</ord:order>'));
クエリの例として、次のようにして、ボブが入力した複数のアイテムを持つすべての注文を検索しようとしました。
SELECT username, itemcount
FROM
(SELECT username,
XMLCAST(XMLQUERY('count(/*:order/*:item)' PASSING order_data RETURNING CONTENT) AS NUMBER) itemcount
FROM orders
)
WHERE username = 'bob'
AND itemcount > 1
ただし、結果は返されませんが、最後の行をコメントアウトすると (AND itemcount > 1)、次のようになります。
username | linecount
--------------------
bob | 2
...理由はわかりませんが、正しい型として扱われていないのではないかと思いましたが、xmlcast で数値としてキャストしています。
さらに不可解なのは、最後の行を次のように設定した場合です。
AND itemcount = 2
...再び消えますが、次のように変更すると:
AND itemcount != -7
...結果に再び表示されますが、値はゼロです:
username | linecount
--------------------
bob | 0
だから、私は困惑しています - 私は何か間違ったことをしているに違いありませんが、それが何であるかわかりません。
xmltable を使用して問題なく動作する回避策を見つけたので、それでうまくいきます:
SELECT username, X.*
FROM orders,
XMLTABLE (
xmlnamespaces ('http://www.blah.com/order/1.0' AS "ord" ),
'/ord:order' PASSING order_data
COLUMNS
itemcount number PATH 'count(ord:item)' ) AS X
WHERE username = 'bob'
AND itemcount > 1