将远程XML数据导入Oracle数据库的问题

时间:2016-07-25 16:01:22

标签: sql xml oracle stored-procedures

在Oracle数据库中,我正在从RESTful Web服务中读取一些XML,如下所示:

<ns1:parent xmlns:ns1="http://www.example.com/xml" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xs1:schemaLocation= "http://www.example.com/xml http://www.w3.org/2001/XMLSchema-instance">
    <ns1:child>
      <ns1:options></ns1:options>
      <ns1:variables></ns1:variables>
      <ns1:values>
        <ns1:value qualifiers="X" date="someTime">Value1</ns1:value>
        <ns1:value qualifiers="X" date="someOtherTime">Value2</ns1:value>
        ...
        <ns1:value qualifiers="X" date="some100thTime">Value100</ns1:value>
      </ns1:values>
    </ns1:child>

然后我尝试使用下面的代码将这些数据提取到数据库中。但是,当我这样做时,它只创建一个只有SYSDATE字段的记录,而其他两个值都是空白的。我也尝试使用XMLTable,但结果相同。我认为命名空间存在问题,但我无法找到正确的语法,而且我尝试过的所有其他组合根本不会返回任何行。

我们还从另一个几乎相同的不使用名称空间的数据源中提取数据,这个代码工作正常(当然没有所有名称空间)。我在某处错误地命名了名称空间的语法吗?

DECLARE
myXMLType XMLType := xmltype(We use a function to pull in the XML file here);
BEGIN
/*Outputting the XMLType here shows that data is in it*/
INSERT INTO output_table 
  SELECT 
    ExtractValue(VALUE(p), '/values/ns1:value', 
        'xmlns:ns1="http://www.example.com/xml"') AS myValue,
    ExtractValue(VALUE(p), '//values/ns1:value/@ns1:date', 
        'xmlns:ns1="http://www.example.com/xml"') AS myTime,
    SYSDATE AS read_date
  FROM 
    TABLE(XMLSequence(EXTRACT(myXMLType, '/ns1:parent/ns1:child/ns1:values', 
        'xmlns:ns1="http://www.example.com/xml"')))p;
  COMMIT; 
END;

1 个答案:

答案 0 :(得分:1)

您可以按照自己的想法使用XMLTable,但需要supply an XMLNameSpaces clause too。这是使用一个名为string的绑定变量来保存您的XML文本(有一些更正):

var string varchar2(200);

begin
  :string := '<ns1:parent xmlns:ns1="http://www.example.com/xml" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  ns1:schemaLocation= "http://www.example.com/xml http://www.w3.org/2001/XMLSchema-instance">
    <ns1:child>
      <ns1:values>
        <ns1:value qualifiers="X" date="someTime">Value1</ns1:value>
        <ns1:value qualifiers="X" date="someOtherTime">Value2</ns1:value>
      </ns1:values>
    </ns1:child>
  </ns1:parent>';
end;
/

SELECT myValue, myTime, SYSDATE AS read_date
FROM XMLTable(XMLNamespaces('http://www.example.com/xml' as "ns1"),
  '/ns1:parent/ns1:child/ns1:values/ns1:value'
  passing XMLType(:string)
  columns myValue varchar2(20) path '.',
    myTime varchar2(20) path '@date'
);

MYVALUE              MYTIME               READ_DATE
-------------------- -------------------- ----------
Value1               someTime             2016-07-25
Value2               someOtherTime        2016-07-25

您可以使用insert ... select子句中的myXMLType变量代替passing,使用XMLType(:string)执行相同的操作。

ExtractValue is deprecated anyway,并且只能返回一个节点,以便在XPath正确的情况下获得ORA-19025。