Oracle xmltable查询/ ORA-19279:XPTY0004 - XQuery动态类型不匹配:预期单例

时间:2015-06-18 11:20:09

标签: oracle xpath

我有这个问题:

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;

所有这一切都行不通,我这样做的原因是为了增加查询whitout上的预编码这个查询非常慢的大型xmls文件

2 个答案:

答案 0 :(得分:0)

这看起来像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,这是更有希望的。

答案 1 :(得分:0)

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  

这一切都对我有好处...如果我找到一种方法(如果有的话)来分离&#34;数据&#34;来自两个查询...