ORA-19280:XQuery动态类型不匹配:预期的原子值-获得节点

时间:2018-11-01 19:22:45

标签: plsql xmltable

我在Oracle中编写了一个存储过程,以使用命名空间读取XML数据。

CREATE OR REPLACE PROCEDURE DynamicXQuery (fileName IN VARCHAR2) 
AS 
    V_TransactionId VARCHAR2(50);

    XPath VARCHAR2(200) := '/message/soap:Envelope/soap:Body/v01:recordTrans';
BEGIN
        SELECT
            X.trans_id
          INTO  
                V_TransactionId 
          FROM  TABLE_WITH_XML_COLUMN T,
                XMLTABLE(
                         XMLNAMESPACES(
                                       'http://schemas.xmlsoap.org/soap/envelope/' as "soap",                            'http://comml.thesoaprequest.com/transactionrecording/v01/' as "v01"
                                      ),
                         '$fullXPath'
                         PASSING T.XML_DOCUMENT, XPath as "fullXPath" 
                         COLUMNS 
                           trans_id VARCHAR2(15) PATH 'transactionIdentifier'
                        ) X
          WHERE T.FILENAME = fileName;

由于“ ORA-19280:XQuery动态类型不匹配:预期的原子值-获取节点”而导致错误

请告知。

谢谢, hu山

1 个答案:

答案 0 :(得分:0)

简短的回答是,在调用XMLTABLE时,很难将文字字符串以外的任何东西用作XQuery字符串,而您正试图做到这一点。您将必须避免以某种方式使用动态XQuery表达式。

通过将XQuery表达式放在变量$fullPath中并在XQuery字符串中使用该变量,无法实现所需的目标。这不会导致Oracle评估XML文档上的XQuery表达式/message/soap:Envelope/soap:Body/v01:recordTrans。相反,它使Oracle评估XML文档上的XQuery表达式'/message/soap:Envelope/soap:Body/v01:recordTrans'。这只是一个文字字符串。它可能是一个文字字符串,恰好包含一个XQuery表达式,但它只是一个对其自身求值的字符串。然后,您将无法查找名为transactionIdentifier的子节点的值,因为字符串只是一个值,所以它没有任何子节点。

如果您只需要XML文档中的单个值,则可以使用EXTRACTVALUE,它对变量XPath表达式没有这种问题,例如:

   SELECT EXTRACTVALUE(
            xml_document,
            XPath || '/transactionIdentifier',
            'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v01="http://comml.thesoaprequest.com/transactionrecording/v01/"'
          )
     INTO V_TransactionId
     FROM table_with_xml_column t
    WHERE t.filename = p_fileName;

另请参阅similar question,该声明基本上指出您问题的答案最终是

  

请勿将变量用作XQuery_string [...]。