【问题标题】:XMLTABLE in oracle how to handle null columns'oracle中的XMLTABLE如何处理空列'
【发布时间】:2020-11-04 13:13:26
【问题描述】:

嗨, 我需要从具有一个 XML 列的表之一中提取数据。 对于某些记录,XML 列没有任何数据。当我使用下面的查询时,我得到了错误。

我们需要运行这个查询,无论该表是否在 XML 列中有数据。

CREATE TABLE XMLTAB_1 (A_ID NUMBER NOT NULL
                   , ID VARCHAR2(50) 
                   , A_DATE DATE 
                   , O_ID NUMBER 
                   , XML_KEY CLOB);


INSERT INTO  XMLTAB_1 (A_ID, ID, A_DATE ,O_ID)
VALUES (11,'SA-AND-11-12345',sysdate,null);
INSERT INTO  XMLTAB_1 (A_ID, ID, A_DATE ,O_ID,XML_KEY )
VALUES (12,'SA-AND-12-12345',sysdate,null,'<?xml version ="1.0" encoding ="UTF-16" standalone="n'"?><al><al_cd><comments><columns><time>2020-07-07 08:45:08 </time><auth>xzy</auth><a_status>new</a_status><assgn>katy</assgn><text>new record </text></columns><columns><time>2020-07-07 09:45:08 </time><auth>abcd</auth><a_status>in progress</a_status><assgn>katy_1</assgn><text>work in progress </text></columns></comments></al_cd></al>');
COMMIT; 
SELECT A_ID
       , ID
       , A_DATE
       , O_ID
       , TO_DATE(C_time,'YYYY_MM_DD HH24:MI:SS') ctime
       , auth
       , status
       , assgn 
       , cmmnt  
       , RANK() OVER (PARTITION BY A_ID ORDER BY TO_DATE(C_time,'YYYY_MM_DD HH24:MI:SS') DESC) rnk
FROM XMLTAB_1 a
     , XMLTABLE('al/al_cd/comments/columns'
           PASSING XMLTYPE(a.XML_KEY) COLUMNS
                c_time   VARCHAR2(100) PATH 'time'
                , auth   VARCHAR2(100) PATH 'auth'
                , status VARCHAR2(100) PATH 'a_status'
                , assgn  VARCHAR2(100) PATH 'assgn'
                , cmmnt  VARCHAR2(100) PATH 'text') xt

我收到错误记录 a_id as 11 fo 12 它工作正常。

ORA-06502: PL/SQL: 数字或值错误 ORA:-06512:at “SYS.XMLTYPE”,第 272 行

谁能告诉我如何实现这一点并从代码中删除错误。

【问题讨论】:

  • 你能复制粘贴表格的DDL吗...也许会有所帮助...
  • CREATE TABLE XMLTAB_1 (A_ID NUMBER NOT NULL, ,ID VARCHAR2(50) ,A_DATE DATE ,O_ID NUMBER XML_KEY CLOB ......);除了这些列之外,还有许多其他列。总列数为 97,无法提供所有其他列的详细信息,因此仅提供我们在 select 语句中使用的选定列的详细信息。
  • 如果你有一个最小的可重现测试用例会容易得多:一个表的 ddl(只有相关的列),几行数据的 dml,然后是 sql抛出此错误。这样,如果 SO 的任何成员想要重现您的示例,他们只需要运行您的脚本即可查看您的错误。不要将它们放在 cmets 中,而是编辑您的问题。
  • 正如@KoenLostrie 所写,您应该向我们提供引发此错误的示例,因为这是我在没有数据的情况下能做的最好的事情:dbfiddle.uk/… 而且您可以看到一切正常...

标签: sql oracle xmltype xmltable


【解决方案1】:

假设您不只是想在 where 子句中完全过滤掉具有空值的行,您可以在 passing 子句中使用 case 表达式:

...
XMLTABLE('al/al_cd/comments/columns'
   PASSING CASE WHEN a.XML_KEY IS NULL THEN NULL ELSE XMLTYPE(a.XML_KEY) END
   COLUMNS c_time VARCHAR2(100) PATH 'time',
...

XPath 看起来很奇怪,可能应该是“/al/al_cd/cmets/columns”,尽管它适用于任何一个。

db<>fiddle 建立在@vBoka 的基础上。我已将旧式交叉联接更改为外部应用,以显示具有空值的行,这需要 Oracle 12c+。

如果您使用的是早期版本,则可以使用具有始终为真条件的外连接,这有点小题大做。 db<>fiddle;或with your sample data,给出:

A_ID | ID              | A_DATE    | O_ID | CTIME     | AUTH | STATUS      | ASSGN  | CMMNT             | RNK
---: | :-------------- | :-------- | ---: | :-------- | :--- | :---------- | :----- | :---------------- | --:
  11 | SA-AND-11-12345 | 15-JUL-20 | null | null      | null | null        | null   | null              |   1
  12 | SA-AND-12-12345 | 15-JUL-20 | null | 07-JUL-20 | abcd | in progress | katy_1 | work in progress  |   1
  12 | SA-AND-12-12345 | 15-JUL-20 | null | 07-JUL-20 | xzy  | new         | katy   | new record        |   2

【讨论】:

  • 感谢 Alex 的解决方案。但我的是 11c,外部应用在其中不起作用。
  • @user8592197 - 你想在输出中看到带有空 XML 的行,对吧?
  • 是的,亚历克斯。我使用不同的块实现了它,但是选择查询需要大量时间才能获得输出。我的表有数百万条记录。
  • 转换所有 XML 然后提取所有值需要一段时间,是的。不知道你所说的块是什么意思;也许是空和非空 CLOB 列值的联合?如果是这样,案例方法可能会更快,但不确定会有很大差异。
  • 非常感谢@AlexPoole!既适用于“CASE WHEN”解决方案,也适用于 dbfiddle 上的 OUTER APPLY 方法 :)
猜你喜欢
  • 2012-09-23
  • 1970-01-01
  • 2017-12-06
  • 1970-01-01
  • 1970-01-01
  • 2014-08-14
  • 2018-12-23
  • 2022-01-14
  • 2012-03-08
相关资源
最近更新 更多