【问题标题】:Use of extractValue function more than one time in oracle give duplicate data from first or last record for all rows在 oracle 中多次使用 extractValue 函数会为所有行提供来自第一条或最后一条记录的重复数据
【发布时间】:2017-10-19 15:52:24
【问题描述】:

假设我有一张客户表。

并且一共有三列(id [type-Number]、name [type-Varchar2]、detail [type-XMLTYPE]。 详细信息列包含客户的 xml 格式的地址,包括他的姓名,与第二列名称相同。

  1. 第一个 sql:工作正常 [两列名称相同]

    SELECT id,
    name,
    extractValue(detail, '/customer/address[@type=''HOME'']/name1') name1
    FROM
    (
        SELECT inner1.*,
        (SELECT detail FROM customer c1 WHERE c1.id = inner1.id) detail
        FROM
        (SELECT c.id, c.name FROM customer c ) inner1
    )
    

    输出:

    1   Janice  Janice
    2   Rita    Rita
    3   Cory    Cory
    
  2. 第二个 sql [无法正常工作:name1 对于第一行的所有行都是重复的]

    SELECT id,
    name,
    extractValue(detail, '/customer/address[@type=''HOME'']/name1') name1,
    extractValue(detail, '/customer/address[@type=''HOME'']/name2') name2
    FROM
      (
        SELECT inner1.*,
              (SELECT detail FROM customer c1 WHERE c1.id = inner1.id) detail
        FROM
          (SELECT c.id, c.name FROM customer c) inner1
      )
    

    输出:

    1   Janice  Janice  Dunn
    2   Rita    Janice  Hale
    3   Cory    Janice  Jones
    

问题:在第二个 sql 中,我只从详细列中请求了额外的数据 name2,这完全改变了输出,因为您可以在第二个 sql 的输出中看到 name1 的重复数据。 这种行为是如何发生的以及可能的解决方案是什么?

如果我不在 sql 的 xpath 中使用属性,则问题不存在。sql 仍然有效并提供正确的数据。 喜欢

extractValue(detail, '/customer/address/name1') name1,

详情

  1. Oracle 数据库 11g 版本 11.2.0.3.0 - 64 位生产
  2. 客户.sql

    创建表“客户”

    (   "ID" NUMBER, 
        "NAME" VARCHAR2(20 BYTE), 
        "DETAIL" "SYS"."XMLTYPE" 
       )
    
     XMLTYPE COLUMN "DETAIL" STORE AS SECUREFILE BINARY XML (
      TABLESPACE "USERS" ENABLE STORAGE IN ROW CHUNK 8192
      CACHE  NOCOMPRESS  KEEP_DUPLICATES 
      STORAGE(INITIAL 106496 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0
      BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)) ALLOW NONSCHEMA DISALLOW ANYSCHEMA ;   
    
    Insert into CUSTOMER (ID,NAME,DETAIL) values (1,'Janice','<?xml version = ''1.0''?><customer>
       <customerno>1</customerno>
       <address type="HOME">
          <name1>Janice</name1>
          <name2>Dunn</name2>
          <email>janice.dunn98@example.com</email>
          <dob>5/2/1980</dob>
          <city>Barn St</city>
       </address>
    </customer>');
    Insert into CUSTOMER (ID,NAME,DETAIL) values (2,'Rita','<?xml version = ''1.0''?><customer>
       <customerno>2</customerno>
       <address type="HOME">
          <name1>Rita</name1>
          <name2>Hale</name2>
          <email>rita.hale40@example.com</email>
          <dob>2/2/1981</dob>
          <city>Seventh St</city>
       </address>
    </customer>');
    Insert into CUSTOMER (ID,NAME,DETAIL) values (3,'Cory','<?xml version = ''1.0''?><customer>
       <customerno>3</customerno>
       <address type="HOME">
          <name1>Cory</name1>
          <name2>Jones</name2>
          <email>cory.jones89@example.com</email>
          <dob>9/7/1984</dob>
          <city>Arther St</city>
       </address>
    </customer>');
    

【问题讨论】:

标签: oracle duplicates xmltype extract-value


【解决方案1】:

EXTRACTVALUE(和 EXTRACT)在 11g 中已弃用。相反,您应该使用 10g 中引入的 XMLTABLE 函数,如下所示:

WITH customer AS (SELECT 1 ID, 'Janice' NAME, XMLTYPE('<?xml version="1.0"?>
<customer><customerno>1</customerno>
   <address type="HOME">
      <name1>Janice</name1>
      <name2>Dunn</name2>
      <email>janice.dunn98@example.com</email>
      <dob>5/2/1980</dob>
      <city>Barn St</city>
   </address>
</customer>') detail FROM dual UNION ALL
                  SELECT 2 ID, 'Rita' NAME , XMLTYPE('<?xml version="1.0"?><customer>
   <customerno>2</customerno>
   <address type="HOME">
      <name1>Rita</name1>
      <name2>Hale</name2>
      <email>rita.hale40@example.com</email>
      <dob>2/2/1981</dob>
      <city>Seventh St</city>
   </address>
</customer>') detail FROM dual UNION ALL
                  SELECT 3 ID, 'Cory' NAME , XMLTYPE('<?xml version="1.0"?><customer>
   <customerno>3</customerno>
   <address type="HOME">
      <name1>Cory</name1>
      <name2>Jones</name2>
      <email>cory.jones89@example.com</email>
      <dob>9/7/1984</dob>
      <city>Arther St</city>
   </address>
</customer>') detail FROM dual)
-- end of mimicking your customer table - you would not need the above, as you already have the table.
-- see the SQL below:
SELECT c.id,
       c.name,
       x.name1,
       x.name2
FROM   customer c
       CROSS JOIN XMLTABLE('/customer' PASSING c.detail
                           COLUMNS name1 VARCHAR2(20) PATH 'address[@type="HOME"]/name1',
                                   name2 VARCHAR2(20) PATH 'address[@type="HOME"]/name2') x;

        ID NAME   NAME1                NAME2
---------- ------ -------------------- --------------------
         1 Janice Janice               Dunn
         2 Rita   Rita                 Hale
         3 Cory   Cory                 Jones

至于你的问题。为什么 EXTRACTVALUE 没有给出正确的结果 - 当我使用与我的答案相同的数据运行您的确切 sql 语句时,我得到完全相同的结果。我在 11.2.0.4,我只能得出结论,如果你得到错误的答案,那一定是你的特定版本的 Oracle 中的一个错误。

我很困惑为什么您要执行标量子查询来检索详细信息列 - 您的 xml 列与您实际数据库中的其余详细信息不在同一个表中吗?

【讨论】:

    猜你喜欢
    • 2012-05-15
    • 2017-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-09
    相关资源
    最近更新 更多