使用XMLCast和XMLQuery的GROUP BY可以得到ORA-22950。

问题描述 投票:2回答:2

下面是我想做的一个例子。

WITH xdata AS
         (SELECT 1 AS a_id,
                 xmltype ('<a>
                    <b>
                        <b_id>1</b_id>
                        <val>2</val>
                    </b>
                    <b>
                        <b_id>1</b_id>
                        <val>3</val>
                    </b>
                 </a>') AS xcol
            FROM DUAL
          UNION ALL
          SELECT 2 AS a_id,
                 xmltype ('<a>
                    <b>
                        <b_id>3</b_id>
                        <val>5</val>
                    </b>
                    <b>
                        <b_id>4</b_id>
                        <val>4</val>
                    </b>
                 </a>') AS xcol
            FROM DUAL)
  SELECT a_id,
         XMLCAST (
             XMLQUERY ('sum($doc/a/b/val/text())'
                       PASSING xcol AS "doc" RETURNING CONTENT) AS INTEGER)
             b_val
    FROM xdata
GROUP BY a_id, xcol;

当我运行上面的查询时,我得到了错误。

ORA-22950: cannot ORDER objects without MAP or ORDER method

如果我删除 GROUP BY 子句,查询工作正常。

我正在处理的现实世界的代码要求我使用的是 GROUP BY 条款。我去了每一个环节,在 该谷歌搜索结果页 但在XML上下文中找不到任何有用的信息。请帮助我理解为什么这个错误也出现在XMLCast和XMLQuery中。

先谢谢你

xml oracle xmltype
2个回答
2
投票

为了通过一个值进行聚合,该值必须是可排序哈希的,这意味着任何两个值都必须是可比的(为了被排序哈希)。XMLType 是不可排序哈希的。在Oracle中,当一个对象类具有以下特殊函数之一时,它就是可哈希的。maporder 定义。见 相关的Oracle文档.

你是通过 xcol,这是一个 XMLType 值。所以,解决你的问题的办法就是通过其他的东西来汇总。


根据你给我们的混乱信息,我想到了两种解决方案......

解决方案1

WITH xdata AS
     (SELECT 1 AS a_id,
             xmltype ('<a>
                <b>
                    <b_id>1</b_id>
                    <val>2</val>
                </b>
                <b>
                    <b_id>1</b_id>
                    <val>3</val>
                </b>
             </a>') AS xcol
        FROM DUAL
      UNION ALL
      SELECT 2 AS a_id,
             xmltype ('<a>
                <b>
                    <b_id>3</b_id>
                    <val>5</val>
                </b>
                <b>
                    <b_id>4</b_id>
                    <val>4</val>
                </b>
             </a>') AS xcol
        FROM DUAL)
SELECT a_id,
     sum(XMLCAST (
         XMLQUERY ('sum($doc/a/b/val)'
                   PASSING xcol AS "doc" RETURNING CONTENT) AS INTEGER))
         b_val
FROM xdata
group by a_id;

解决方案2

WITH xdata AS
     (SELECT 1 AS a_id,
             xmltype ('<a>
                <b>
                    <b_id>1</b_id>
                    <val>2</val>
                </b>
                <b>
                    <b_id>1</b_id>
                    <val>3</val>
                </b>
             </a>') AS xcol
        FROM DUAL
      UNION ALL
      SELECT 2 AS a_id,
             xmltype ('<a>
                <b>
                    <b_id>3</b_id>
                    <val>5</val>
                </b>
                <b>
                    <b_id>4</b_id>
                    <val>4</val>
                </b>
             </a>') AS xcol
        FROM DUAL)
select X.a_id, sum(Y.b_val) as b_val
from xdata X
    cross join xmltable(
        '/a/b'
        passing X.xcol
        columns
            b_val integer path 'val'
    ) Y
group by X.a_id;

0
投票

可能真的很晚才提出解决方案,但我最近在使用 摘取xmltype 在同一个查询中,为了检索某些xml数据,能够像这样克服它。

解决办法

select result, count(*) from (
   select extract(xmltype(xml_payload),'xpath','namespacedefinition').getStringVal() as result from x_table
) group by result;

当然主查询的包装是没有必要的。

祝大家好运!

© www.soinside.com 2019 - 2024. All rights reserved.