【问题标题】:Oracle xmltable query / ORA-19279: XPTY0004 - XQuery dynamic type mismatch: expected singletonOracle xmltable 查询 / ORA-19279:XPTY0004 - XQuery 动态类型不匹配:预期单例
【发布时间】:2015-09-04 00:10:15
【问题描述】:

我有这个问题:

SELECT   TYPE,  IDVIEW,  ATTRIBUTE,  VALUE
FROM XML_IMPORT_REPOSITORY t
CROSS JOIN XMLTABLE ('for $item in /SRDBSW/OBJ_DF[@IdView="ICU-ASW"]/*[@IdView] 
                          for $item_attr in $item/@*  
                          return element {$item/name(.)} 
                          {                     
                            element idview {$item/@IdView/string()},
                            element attr {$item_attr/local-name(.)},
                            element value {$item_attr/string()}
                          }
                          ' PASSING t.XMLDATA COLUMNS 
                          TYPE VARCHAR2(30) PATH 'local-name(.)', 
                          IDVIEW VARCHAR2(30) PATH 'idview', 
                          attribute VARCHAR2(30) PATH 'attr', 
                          value VARCHAR2(30) PATH 'value' ) x

我收到此错误:

ORA-19279:XPTY0004 - XQuery 动态类型不匹配:预期单例 序列 - 得到多项序列 19279. 00000 -“XPTY0004 - XQuery 动态类型不匹配:预期的单例序列 - 得到多项序列”

我发现了问题,问题是这一行:

 element value {$item_attr/string()}

但找不到解决方法来获取属性的值...

xml 中的一个示例

<OBJ_DF IdView="ICU-ASW" CategoryFlag="0" OwnerFlag="0" ObjLevel="Element" IsDefined="Y" ShortDescription="CONFIG Major function" ShortDescriptionCore="CONFIG Major function" LongDescription="CONFIG Major function Manual Load" Mnemonic="CONFIG Major function">
        <TEXTUAL_CURVE_DF IdView="0001" ShortDescription="PhysSide octet" ShortDescriptionCore="PhysSide octet" LongDescription="Type identifying the physical side of a unit in 8 bits" Mnemonic="Physical_Side_Octet_T" CategoryFlag="0" OwnerFlag="0" IsDirect="Y" Type="CURVE" CurveType="Textual" RawFormat="Unsigned Integer">
            <DIG_POINT_LIST>
                <DIG_POINT LowValue="0" StatusText="SIDE_1" Mnemonic="Side_1" Ldesc="FCI/Config/Physical_Side_Octet.Side_1" HighValue="0"/>
                <DIG_POINT LowValue="1" StatusText="SIDE_2" Mnemonic="Side_2" Ldesc="FCI/Config/Physical_Side_Octet.Side_2" HighValue="1"/>
            </DIG_POINT_LIST>
        </TEXTUAL_CURVE_DF>
        <TEXTUAL_CURVE_DF IdView="0002" ShortDescription="Health_T" ShortDescriptionCore="Health_T" LongDescription="Type for Health of unit or equipment" Mnemonic="Health_T" CategoryFlag="0" OwnerFlag="0" IsDirect="Y" Type="CURVE" CurveType="Textual" RawFormat="Unsigned Integer">
            <DIG_POINT_LIST>
                <DIG_POINT LowValue="0" StatusText="UNHEALTHY" Mnemonic="Unhealthy" Ldesc="FCI/Config/Health.Unhealthy" HighValue="0"/>
                <DIG_POINT LowValue="1" StatusText="HEALTHY" Mnemonic="Healthy" Ldesc="FCI/Config/Health.Healthy" HighValue="1"/>
            </DIG_POINT_LIST>
        </TEXTUAL_CURVE_DF>
        <TEXTUAL_CURVE_DF IdView="0003" ShortDescription="Logical_Power_T" ShortDescriptionCore="Logical_Power_T" LongDescription="Type for Logical On or Off status of unit or equipment" Mnemonic="Logical_Power_T" CategoryFlag="0" OwnerFlag="0" IsDirect="Y" Type="CURVE" CurveType="Textual" RawFormat="Unsigned Integer">
            <DIG_POINT_LIST>
                <DIG_POINT LowValue="0" StatusText="OFF" Mnemonic="Off" Ldesc="FCI/Config/Logical_Power.Off" HighValue="0"/>
                <DIG_POINT LowValue="1" StatusText="ON" Mnemonic="On" Ldesc="FCI/Config/Logical_Power.On" HighValue="1"/>
            </DIG_POINT_LIST>
        </TEXTUAL_CURVE_DF>
    </OBJ_DF>

查询应该返回项目的名称,所有都是属性

工作集是:

CREATE OR REPLACE directory XTDIR AS 'C:\Users\aadr\Documents\SCCOPEN\NEW-IMPORT\demo';


BEGIN
  DBMS_XMLSCHEMA.registerSchema(
    SCHEMAURL => 'http://www.w3.org/2001/XMLSchema',
    SCHEMADOC => bfilename('XTDIR','SRDBSW_schema_full.xsd'));
END;

CREATE TABLE XML_IMPORT_REPOSITORY (xmlkey VARCHAR(20) PRIMARY KEY, xmlData XMLType)
    xmltype column xmlData  XMLSCHEMA "http://www.w3.org/2001/XMLSchema" 
  element "SRDBSW" tablespace USERS;

   INSERT INTO XML_IMPORT_REPOSITORY(XMLKEY, XMLDATA) VALUES 
   ('full',XMLType(bfilename('XTDIR', 'full.xml'), nls_charset_id('AL32UTF8')));

   commit;

所有这些都不起作用,我这样做的原因是为了增加查询的性能,而这个查询对于大型 xmls 文件来说非常慢

【问题讨论】:

  • 您能否添加一个生成错误的小示例 XML 文档?
  • 它在 11.2.0.3 中对我来说很好用(带有封闭的 SRDBSW 标记)。你在什么版本下运行这个?
  • Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
  • 你可以试试element value {$item_attr[1]/string()} - 即添加[1] 吗?
  • 元素值 {$item_attr[1]/string()} ,同样的错误 ORA-19279: XPTY0004 - XQuery 动态类型不匹配:预期的单例序列 - 得到多项序列

标签: oracle xpath


【解决方案1】:
SELECT x.*  FROM XML_IMPORT_REPOSITORY t 
CROSS JOIN XMLTABLE ('/SRDBSW/OBJ_DF/*[/SRDBSW/OBJ_DF/@IdView="ICU-ASW"]' 
          PASSING t.XMLDATA   
          COLUMNS IdView VARCHAR2(30) PATH '@IdView', 
          attr_name VARCHAR2(30) PATH 'local-name(.)') x 
union   all        
SELECT z.* FROM XML_IMPORT_REPOSITORY tt 
CROSS JOIN XMLTABLE ('/SRDBSW/OBJ_DF/*[/SRDBSW/OBJ_DF/@IdView="ICU-ASW"]/@*' 
          PASSING tt.XMLDATA   
          COLUMNS  
          attr_name  VARCHAR2(30) PATH 'local-name(.)',
          attr_value VARCHAR2(30) PATH '.') z  

这一切都对我有好处...如果我找到一种方法(如果有的话)将“数据”与两个查询分开...

【讨论】:

    【解决方案2】:

    这看起来像 bug 13060499,与 7554407 相关;请参阅 My Oracle Support 文档 ID 1373311.1。虽然没有太多信息。已知它会影响 11.2.0.2,但尚不清楚它是否或何时修复 - 我在 11.2.0.3 中看不到此问题,因此它可能已在该补丁集中悄悄修复。

    一种解决方法似乎是向属性引用添加应该是冗余索引的内容:

    element value {$item_attr[1]/string()}
    

    但由于它本身似乎没有帮助,也许将它添加到所有内容中:

    SELECT   TYPE,  IDVIEW,  ATTRIBUTE,  VALUE
    FROM XML_IMPORT_REPOSITORY t
    CROSS JOIN XMLTABLE ('for $item in /SRDBSW/OBJ_DF[@IdView="ICU-ASW"]/*[@IdView] 
                              for $item_attr in $item[1]/@*  
                              return element {$item[1]/name(.)} 
                              {                     
                                element idview {$item[1]/@IdView[1]/string()},
                                element attr {$item_attr[1]/local-name(.)},
                                element value {$item_attr[1]/string()}
                              }
                              ' PASSING t.XMLDATA COLUMNS 
                              TYPE VARCHAR2(30) PATH 'local-name(.)', 
                              IDVIEW VARCHAR2(30) PATH 'idview', 
                              attribute VARCHAR2(30) PATH 'attr', 
                              value VARCHAR2(30) PATH 'value' ) x;
    

    在 11.2.0.3 中,结果与没有节点索引相同。我没有 11.2.0.2 实例来验证它(并且 SQL Fiddle,即那个版本,没有有用的消息就失败了)。

    您也可以在 XQuery 中使用单个 for 执行此操作,方法是直接进入属性级别,然后使用 ../ 引用父节点:

    SELECT TYPE, IDVIEW, ATTRIBUTE, VALUE
    FROM XML_IMPORT_REPOSITORY t
    CROSS JOIN XMLTABLE ('for $item_attr in
        /SRDBSW/OBJ_DF[@IdView="ICU-ASW"]/*[@IdView]/@*
      return element {$item_attr[1]/../name(.)} 
      {                     
        element idview {$item_attr[1]/../@IdView[1]/string()},
        element attr {$item_attr[1]/local-name(.)},
        element value {$item_attr[1]/string()}
      }'
      PASSING t.XMLDATA
      COLUMNS 
        TYPE VARCHAR2(30) PATH 'local-name(.)', 
        IDVIEW VARCHAR2(30) PATH 'idview', 
        attribute VARCHAR2(30) PATH 'attr', 
        value VARCHAR2(30) PATH 'value' ) x;
    

    我留下了[1],以防万一它仍然有用/需要。但是 SQL Fiddle 现在可以在 withwithout 上运行,这很有前途。

    【讨论】:

    • 如果它是一个已修复的错误,那么可以,并且修补到 11.2.0.3 或 11.2.0.4(加上 PSU)无论如何都不是一个坏主意。第二个查询,带有一个 for,可能适用于您所拥有的。也许吧。
    • @AntónioRoque - 第二个查询呢,只有for
    • 一些链接到相同的样本..看看你在想什么?
    • 该下班了,明天我可以得到“请”吗?
    • @AntónioRoque - 我不知道你在问什么。我已经给出了两个查询来尝试。你说第一个不行。你还没有说你是否尝试过第二个。我不知道你指的是什么样本。
    猜你喜欢
    • 2017-07-12
    • 1970-01-01
    • 1970-01-01
    • 2016-08-23
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多