如何在oracle中解析CDATA中的数据

时间:2017-04-10 11:24:26

标签: sql oracle

表中有一个类型为field2的列,它存储有效负载。

我需要获得与 $("#thisisform").submit( function(e) { e.preventDefault(); // added code loadAjax(); e.returnValue = false; }); 相关的值(在本例中为7)。如何编写查询以获得相同的信息。由于CLOB的顺序从记录更改为记录,因此无法使用tenantIdsubstr

instr

2 个答案:

答案 0 :(得分:2)

在Oracle 12中,您应该能够:

SELECT tenantId
FROM   your_table t
       LEFT OUTER JOIN
       XMLTABLE(
         '/PayLoad/.'
         PASSING XMLTYPE( t.your_xml_column )
         COLUMNS cdata CLOB PATH '.'
       ) x
       ON ( 1 = 1 )
       LEFT OUTER JOIN
       JSON_TABLE(
         x.cdata,
         '$'
         COLUMNS ( tenantId VARCHAR2(10) PATH '$.order.tenantId' )
       ) j
       ON ( 1 = 1 );

(未经测试,因为我接下来的几个小时是11g)

在Oracle 11上:

SELECT REGEXP_SUBSTR( x.cdata, '"tenantId":"((\\"|[^"])*)"', 1, 1, NULL, 1 ) AS tenantId
FROM   your_table t
       LEFT OUTER JOIN
       XMLTABLE(
         '/PayLoad/.'
         PASSING XMLTYPE( t.your_xml_column )
         COLUMNS cdata CLOB PATH '.'
       ) x
       ON ( 1 = 1 )

或者(如果JSON字符串不会出现在XML的另一个分支中),您可以使用:

SELECT REGEXP_SUBSTR(
         your_xml_column,
         '"tenantId":"((\\"|[^"])*)"',
         1,
         1,
         NULL,
         1
       ) AS tenantId
FROM   your_table

答案 1 :(得分:2)

您的CDATA有效负载似乎是JSON,因此如果您使用的是12c且每个CDATA只有一个订单,则可以执行以下操作:

select json_value(x.cdata, '$.order.tenantId' returning number) as tenantid
from your_table t
cross join xmltable('/PayLoad'
  passing xmltype(your_clob)
  columns cdata clob path './text()'
) x;

正如@MTO指出的那样,将JSON值视为数字可能无效,因为它在原始JSON中显示为字符串。使其returning varchar2(10)或其他合适的尺寸可能更合适(并且更安全,至少在您使用之前)。

使用XML作为CTE进行快速演示:

with your_table (your_clob) as (
  select to_clob('<PayLoad><![CDATA[{"order":{"entityErrors":[],"action":"CONFIRM","tenantId":"7","Id":"2","deliveryReservationDetails":[{"reservationId":"c05e0c77-1c8f-4dce-a388-fe97fd36f96e","fulfillmentLocationType":"Store"}]}}]]></PayLoad>') from dual
)
select json_value(x.cdata, '$.order.tenantId' returning number) as tenantid
from your_table t
cross join xmltable('/PayLoad'
  passing xmltype(your_clob)
  columns cdata clob path './text()'
) x;

TENANTID               
---------------------- 
7