我有一个带有 xmltype 列和其他非 xmltype 列的表(Oracle 11.2.0.2)。我想根据一些非 xmltype 列的值加上 xmltype 列的内容进行选择。
我已经尝试在我的选择中使用 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>'));
作为示例查询,我尝试通过执行以下操作查找 Bob 输入的所有超过 1 个项目的订单:
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