извлечь значение, присутствующее между тегами XML из BLOB-объекта в Oracle SQL - PullRequest
0 голосов
/ 06 июля 2018

эти данные присутствуют в блоке COLUMN ("MSG") в моей таблице ADMINTXNUNAUTHDATA

<PayBillerRequestDTO><idCustomer>00000024</idCustomer><idBiller>VODA</idBiller><billerName>ojas yadnik </billerName><billReferenceNumber>111</billReferenceNumber></PayBillerRequestDTO>

Я хочу показать "111" между <billReferenceNumber>111</billReferenceNumber>

и некоторые другие значения из разных таблиц в одном запросе

select mbl.idbiller as BILLNUMBER,
       mbl.billernickname AS BILLERNICKNAME,
       mts.idchanneluser AS USERNAME,
       adm.NUMAMOUNT AS AMOUNT,
       adm.ACCOUNTNO AS ACCOUNTNUM,
       adm.DATINITIATION AS TRANSACTIONDATE,
       adm.codcurr as CURRENCY
  from mstbiller mbl, ADMINTXNUNAUTHDATA adm, mstchanneluser mts
 where MTS.IDCHANNELUSER = '??'
   and adm.idinitiator = mts.iduser 
   and adm.txnid = 'BPA'
   and mbl.idbiller ='?'
   AND dbms_lob.instr(MSG, utl_raw.CAST_TO_RAW('<idBiller>?</idBiller>'), 1, 1) > 0;

Ответы [ 3 ]

0 голосов
/ 06 июля 2018

Я бы не советовал искать теги XML с INSTR, так как он чувствителен к пространству, например, он не найдет <idBiller>111</idBiller > или <idBiller a="x">111</idBiller>. В конце концов, это XML, который якобы легко разобрать. (Впрочем, никто не упоминал об этом синтаксисе).

Во-вторых, BLOB - это совершенно неправильный тип данных. Это для двоичных данных. Просто подождите, пока первый клиент по имени Agüero или Jørgensen. Подходящий тип данных для XML в Oracle: XMLTYPE:

CREATE TABLE admintxnunauthdata (
  accountno NUMBER,
  msg XMLTYPE
) XMLTYPE COLUMN msg STORE AS SECUREFILE BINARY XML (COMPRESS HIGH);

INSERT INTO admintxnunauthdata (accountno, msg) VALUES (1,
 '<PayBillerRequestDTO><idCustomer>00000024</idCustomer><idBiller>VODA</idBiller><billerName>ojas yadnik </billerName><billReferenceNumber>111</billReferenceNumber></PayBillerRequestDTO>');
INSERT INTO admintxnunauthdata (accountno, msg) VALUES (2,
 '<PayBillerRequestDTO><idCustomer>00000025</idCustomer><idBiller>JODA</idBiller><billerName>ojas yadnik </billerName><billReferenceNumber>222</billReferenceNumber></PayBillerRequestDTO>');

Затем вы можете искать записи по idBiller:

SELECT * 
  FROM admintxnunauthdata
 WHERE XMLExists('/PayBillerRequestDTO[idBiller="VODA"]' PASSING msg);

и извлечение значений тегов из XML:

SELECT accountno,
       XMLQuery('/PayBillerRequestDTO/billReferenceNumber/text()' 
         PASSING msg RETURNING CONTENT)
  FROM admintxnunauthdata
 WHERE XMLExists('/PayBillerRequestDTO[idBiller="VODA"]' PASSING msg);

Чтобы преобразовать текст XML в обычный тип данных, используйте

SELECT accountno,
       XMLCast(XMLQuery('/PayBillerRequestDTO/billReferenceNumber/text()' 
         PASSING msg RETURNING CONTENT) AS NUMBER) AS billreferencenumber
  FROM admintxnunauthdata
 WHERE XMLExists('/PayBillerRequestDTO[idBiller="VODA"]' PASSING msg);

ACCOUNTNO BILLREFERENCENUMBER
        1                 111

Если вы не можете изменить (или позволить изменить) структуру таблицы, вы можете теоретически преобразовать BLOB-объект в XMLTYPE на лету, но я понятия не имею о влиянии на производительность:

SELECT accountno,
       XMLCast(XMLQuery('/PayBillerRequestDTO/billReferenceNumber/text()' 
         PASSING msg RETURNING CONTENT) AS NUMBER) AS billreferencenumber
  FROM (
        SELECT accountno, XMLTYPE(msg,1) as msg 
          FROM admintxnunauthdata
       )
 WHERE XMLExists('/PayBillerRequestDTO[idBiller="VODA"]' PASSING msg);

Для преобразования из BLOB в XMLTYPE, см. преобразование Oracle Blob в тип XML

0 голосов
/ 06 июля 2018

Конструктор Xmltype переопределен. Одна версия - xmltype (blob, csid), капля капля, csid - это идентификационный номер набора символов, соответствующий имени набора символов. Для utf8 это 871.

Проверьте пример. Первая часть предназначена только для подготовки значения BLOB-объекта. Во 2-й части я конвертирую BLOB-объекты в xml с помощью csid и извлекаю данные из xml с использованием xmltable.

    create table blob_xml (a blob);

    declare 
      cisd number;
      myblob blob;
    begin 
-- save xml as blob
        SELECT NLS_CHARSET_ID('UTF8') into cisd FROM DUAL; 
        myblob := xmltype('<PayBillerRequestDTO><idCustomer>00000024</idCustomer><idBiller>VODA</idBiller><billerName>ojas yadnik </billerName><billReferenceNumber>111</billReferenceNumber></PayBillerRequestDTO>').getblobVal(cisd); 
       insert into blob_xml values(myblob);
       commit;
    end; 


        select * from blob_xml,xmltable('PayBillerRequestDTO' passing xmltype(a,871)
      columns idCustomer varchar2(4000) path 'idCustomer'
      ,idBiller varchar2(4000) path 'idBiller'
      ,billerName  varchar2(4000) path 'billerName'
      ,billReferenceNumber varchar2(4000) path 'billReferenceNumber'
      --etc
       )

;

Я предполагаю, что ваш xml кодируется с помощью utf8

0 голосов
/ 06 июля 2018

Вы можете использовать SUBSTRING_INDEX , чтобы сделать это:

Пример:

MariaDB [(none)]> SET @x:="<PayBillerRequestDTO><idCustomer>00000024</idCustomer><idBiller>VODA</idBiller><billerName>ojas yadnik </billerName><billReferenceNumber>111</billReferenceNumber></PayBillerRequestDTO>";
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> SELECT SUBSTRING_INDEX( SUBSTRING_INDEX( @x, "<billReferenceNumber>", -1), '</billReferenceNumber>', 1) as result;
+--------+
| result |
+--------+
| 111    |
+--------+
1 row in set (0.00 sec)

MariaDB [(none)]>
...