2017-01-26 20 views
0

Я ищу решение для получения данных из XML-строки, хранящейся в столбце DB БД Oracle, чтобы вставить их в две разные таблицы: table_1 & table_2.Orcale 11g: Чтение записей в XML из CLOB и обновления таблицы

Вот мой XML строка:

 <?xml version="1.0" encoding="utf-8"?> 
     <FIC> 
      <LIS_UAT> 
      <UAT> 
       <COD_SOC>1000</COD_SOC> 
       <COD_ETA>1010</COD_ETA> 
       <NUM_UAT>0080000228</NUM_UAT> 
       <DATA> 
       <COD_DEV_MAR></COD_DEV_MAR> 
       <COD_TRS_FAC>9000000026</COD_TRS_FAC> 
       <MNT_MAR>525</MNT_MAR> 
       <NBR_COL>500</NBR_COL> 
       <NBR_MET_LIN>0.25</NBR_MET_LIN> 
       <PDS_BRT>138</PDS_BRT> 
       <PDS_NET>110</PDS_NET> 
       <VAL_SURF>4</VAL_SURF> 
       <VOL>1</VOL> 
       </DATA> 
       <LIS_PRO> 
       <PRO> 
        <COD_PRO>110089</COD_PRO> 
        <NBR_COL>500</NBR_COL> 
        <PRX>400</PRX> 
        <QTE>250</QTE> 
        <LIB_PRO_DST>MILK POWDER 28.8% CREAM BAG 25 KG IN BULK</LIB_PRO_DST> 
        <NUM_LOT>LOT1</NUM_LOT> 
        <DAT_DLC>2017-01-22T00:00:00</DAT_DLC> 
        <LIB_PRO>MILK POWDER 28.8% CREAM BAG 25 KG IN BULK</LIB_PRO> 
        <COL_PDS>0.267</COL_PDS> 
        <COL_VOL>0.002</COL_VOL> 
        <PCB>1</PCB> 
        <PDS_BRT>0.267</PDS_BRT> 
        <PDS_NET>0.267</PDS_NET> 
        <VOL>0.002</VOL> 
        <COD_EAN>1000</COD_EAN> 
        <COD_TRS>FOURNISSEUR</COD_TRS> 
       </PRO> 
       <PRO> 
        <COD_PRO>110090</COD_PRO> 
        <NBR_COL>50</NBR_COL> 
        <PRX>40</PRX> 
        <QTE>25</QTE> 
        <LIB_PRO_DST>MILK POWDER 40% CREAM BAG 25 KG</LIB_PRO_DST> 
        <NUM_LOT>LOT2</NUM_LOT> 
        <DAT_DLC>2017-02-25T00:00:00</DAT_DLC> 
        <LIB_PRO>MILK POWDER 40% CREAM BAG 25 KG</LIB_PRO> 
        <COL_PDS>0.167</COL_PDS> 
        <COL_VOL>0.001</COL_VOL> 
        <PCB>1</PCB> 
        <PDS_BRT>0.267</PDS_BRT> 
        <PDS_NET>0.267</PDS_NET> 
        <VOL>0.002</VOL> 
        <COD_EAN>1001</COD_EAN> 
        <COD_TRS>SYNUTRA</COD_TRS> 
       </PRO> 
       </LIS_PRO> 
      </UAT> 
      <UAT> 
       <COD_SOC>1000</COD_SOC> 
       <COD_ETA>1010</COD_ETA> 
       <NUM_UAT>0080000229</NUM_UAT> 
       <DATA> 
       <COD_DEV_MAR></COD_DEV_MAR> 
       <COD_TRS_FAC>9000000027</COD_TRS_FAC> 
       <MNT_MAR>52.5</MNT_MAR> 
       <NBR_COL>50</NBR_COL> 
       <NBR_MET_LIN>0.025</NBR_MET_LIN> 
       <PDS_BRT>13.8</PDS_BRT> 
       <PDS_NET>11</PDS_NET> 
       <VAL_SURF>0.4</VAL_SURF> 
       <VOL>1</VOL> 
       </DATA> 
       <LIS_PRO> 
       <PRO> 
        <COD_PRO>82</COD_PRO> 
        <NBR_COL>5000</NBR_COL> 
        <PRX>4000</PRX> 
        <QTE>2500</QTE> 
        <LIB_PRO_DST>DMU Lait non traité -interface SPX !!S2a</LIB_PRO_DST> 
        <NUM_LOT>LOT3</NUM_LOT> 
        <DAT_DLC>2017-03-15T00:00:00</DAT_DLC> 
        <LIB_PRO>DMU Lait non traité -interface SPX !!S2a</LIB_PRO> 
        <COL_PDS>16.7</COL_PDS> 
        <COL_VOL>1</COL_VOL> 
        <PCB>1</PCB> 
        <PDS_BRT>267</PDS_BRT> 
        <PDS_NET>267</PDS_NET> 
        <VOL>2</VOL> 
        <COD_EAN>1003</COD_EAN> 
        <COD_TRS>0000001001</COD_TRS> 
       </PRO> 
       </LIS_PRO> 
      </UAT> 
      </LIS_UAT> 
     </FIC> 
  • значение элементов в узлах будут проверяться на наличие в table_1
  • Если да значение элементов в узлах будут объединены в table_1
  • значение элементов в Узлы будут вставлены (после подавления) в таблице_2

=> table_2 поля справок (FK) CO D_SOC, COD_ETA и NUM_UAT из table_1 (PK)

Я сделал это, чтобы вывести результат, но у меня есть декартово произведение (я не нашел способ вступайте в разные XMLTABLES

 ALTER SESSION SET nls_numeric_characters = '. '; 

     DECLARE 
     BEGIN 
      FOR uat_crs 
       IN (SELECT x1.num_uat as num_uat,x2.nbr_col as nbr_col,x3.cod_pro as cod_pro 
        FROM pro_ficj a, 
          XMLTABLE (
          '/FIC/LIS_UAT/UAT' 
          PASSING A.DOC_XML 
          COLUMNS COD_SOC VARCHAR2 (5) PATH 'COD_SOC', 
            COD_ETA VARCHAR2 (5) PATH 'COD_ETA', 
            NUM_UAT VARCHAR2 (17) PATH 'NUM_UAT') x1, 
            XMLTABLE (
            '/FIC/LIS_UAT/UAT/DATA' 
            PASSING A.DOC_XML 
            COLUMNS COD_DEV_MAR VARCHAR2 (3) PATH 'COD_DEV_MAR', 
              COD_TRS_FAC VARCHAR2 (17) PATH 'COD_TRS_FAC', 
              MNT_MAR NUMBER (10, 2) PATH 'MNT_MAR', 
              NBR_COL NUMBER (16) PATH 'NBR_COL', 
              NBR_MET_LIN NUMBER (16, 3) PATH 'NBR_MET_LIN', 
              PDS_BRT NUMBER (10, 3) PATH 'PDS_BRT', 
              PDS_NET NUMBER (10, 3) PATH 'PDS_NET', 
              VAL_SURF NUMBER (16, 3) PATH 'VAL_SURF', 
              VOL NUMBER (9, 3) PATH 'VOL') X2 
          ,XMLTABLE ('/FIC/LIS_UAT/UAT/LIS_PRO/PRO' 
                PASSING A.DOC_XML 
                COLUMNS COD_PRO     VARCHAR2 (17)PATH 'COD_PRO', 
                  NBR_COL     NUMBER (5) PATH 'NBR_COL', 
                  PRX      NUMBER (16,7) PATH 'PRX', 
                  QTE      NUMBER (16) PATH 'QTE', 
                  LIB_PRO_DST    VARCHAR2 (50) PATH 'LIB_PRO_DST', 
                  NUM_LOT     VARCHAR2 (17) PATH 'NUM_LOT', 
                  DAT_DLC     varchar2(50) PATH 'DAT_DLC', 
                  LIB_PRO     VARCHAR2 (70) PATH 'LIB_PRO', 
                  COL_PDS     NUMBER (10, 3) PATH 'COL_PDS', 
                  COL_VOL     NUMBER (11, 4) PATH 'COL_VOL', 
                  PCB      NUMBER (4) PATH 'PCB', 
                  PDS_BRT     NUMBER (10, 3) PATH 'PDS_BRT', 
                  PDS_NET     NUMBER (10,3) PATH 'PDS_NET', 
                  VOL      NUMBER (9,3) PATH 'VOL', 
                  COD_EAN     VARCHAR2 (17) PATH 'COD_EAN', 
                  COD_TRS     VARCHAR2 (17) PATH 'COD_TRS' 
                  ) X3 
        WHERE a.num_int_jrn = 881) 
      LOOP 



       DBMS_OUTPUT.PUT_LINE('uatv : ' || uat_crs.num_uat || ' - data : ' || uat_crs.NBR_COL ||' - pro : ' || uat_crs.COD_PRO); 

       END LOOP; 

     END; 
     /

Спасибо большое ,

IT

ответ

0

Наконец я нашел решение:

ALTER SESSION SET nls_numeric_characters = '. '; 

Declare 


BEGIN 
    FOR uat_crs 
     IN ( SELECT x1.cod_soc AS COD_SOC, 
         x1.cod_eta AS COD_ETA, 
         x1.num_uat AS NUM_UAT, 
         'U' AS TYP_UAT, 
         X2.* 
       FROM pro_ficj a, 
         XMLTABLE ('/FIC/LIS_UAT/UAT' 
           PASSING A.DOC_XML 
           COLUMNS COD_SOC VARCHAR2 (5) PATH 'COD_SOC', 
             COD_ETA VARCHAR2 (5) PATH 'COD_ETA', 
             NUM_UAT VARCHAR2 (17) PATH 'NUM_UAT', 
             DATA XMLTYPE PATH 'DATA') x1, 
         XMLTABLE (
         '/DATA' 
         PASSING X1.DATA 
         COLUMNS COD_DEV_MAR VARCHAR2 (3) PATH 'COD_DEV_MAR', 
           COD_TRS_FAC VARCHAR2 (17) PATH 'COD_TRS_FAC', 
           MNT_MAR NUMBER (10, 2) PATH 'MNT_MAR', 
           NBR_COL NUMBER (16) PATH 'NBR_COL', 
           NBR_MET_LIN NUMBER (16, 3) PATH 'NBR_MET_LIN', 
           PDS_BRT NUMBER (10, 3) PATH 'PDS_BRT', 
           PDS_NET NUMBER (10, 3) PATH 'PDS_NET', 
           VAL_SURF NUMBER (16, 3) PATH 'VAL_SURF', 
           VOL NUMBER (9, 3) PATH 'VOL') x2 
       WHERE num_int_jrn = 881) 
    LOOP 
     DBMS_OUTPUT.put_line ('UAT : ' || uat_crs.num_uat); 
     DBMS_OUTPUT.PUT_LINE (
      'data : ' 
     || uat_crs.COD_DEV_MAR 
     || ' - ' 
     || uat_crs.COD_TRS_FAC 
     || ' - ' 
     || uat_crs.NBR_COL 
     || ' - ' 
     || uat_crs.NBR_MET_LIN 
     || ' - ' 
     || uat_crs.PDS_BRT 
     || ' - ' 
     || uat_crs.PDS_NET 
     || ' - ' 
     || uat_crs.VAL_SURF 
     || ' - ' 
     || uat_crs.VOL); 


     FOR pro_crs 
     IN ( SELECT y1.cod_soc, 
         y1.cod_eta, 
         y1.num_uat, 
         y2.* 
        FROM pro_ficj a, 
         XMLTABLE ('/FIC/LIS_UAT/UAT' 
            PASSING A.DOC_XML 
            COLUMNS COD_SOC VARCHAR2 (5) PATH 'COD_SOC', 
              COD_ETA VARCHAR2 (5) PATH 'COD_ETA', 
              NUM_UAT VARCHAR2 (17) PATH 'NUM_UAT', 
              PRODUITS XMLTYPE PATH 'LIS_PRO') y1, 
         XMLTABLE (
          '/LIS_PRO/PRO' 
          PASSING y1.produits 
          COLUMNS COD_PRO VARCHAR2 (17) PATH 'COD_PRO', 
            NBR_COL NUMBER (5) PATH 'NBR_COL', 
            PRX NUMBER (16, 7) PATH 'PRX', 
            QTE NUMBER (16) PATH 'QTE', 
            LIB_PRO_DST VARCHAR2 (50) PATH 'LIB_PRO_DST', 
            NUM_LOT VARCHAR2 (17) PATH 'NUM_LOT', 
            DAT_DLC VARCHAR2 (50) PATH 'DAT_DLC', 
            LIB_PRO VARCHAR2 (70) PATH 'LIB_PRO', 
            COL_PDS NUMBER (10, 3) PATH 'COL_PDS', 
            COL_VOL NUMBER (11, 4) PATH 'COL_VOL', 
            PCB NUMBER (4) PATH 'PCB', 
            PDS_BRT NUMBER (10, 3) PATH 'PDS_BRT', 
            PDS_NET NUMBER (10, 3) PATH 'PDS_NET', 
            VOL NUMBER (9, 3) PATH 'VOL', 
            COD_EAN VARCHAR2 (17) PATH 'COD_EAN', 
            COD_TRS VARCHAR2 (17) PATH 'COD_TRS') y2 
        WHERE  a.num_int_jrn = 881 
         AND y1.cod_soc = uat_crs.cod_soc 
         AND y1.cod_eta = uat_crs.cod_eta 
         AND y1.num_uat = uat_crs.num_uat) 
     LOOP 
     DBMS_OUTPUT.put_line ('-> Produit : ' || pro_crs.cod_pro); 

     DBMS_OUTPUT.PUT_LINE (
       'pro : ' 
      || pro_crs.COD_PRO 
      || ' - ' 
      || pro_crs.NBR_COL 
      || ' - ' 
      || pro_crs.PRX 
      || ' - ' 
      || pro_crs.QTE 
      || ' - ' 
      || pro_crs.LIB_PRO_DST 
      || ' - ' 
      || pro_crs.NUM_LOT 
      || ' - ' 
      || pro_crs.DAT_DLC 
      || ' - ' 
      || pro_crs.LIB_PRO 
      || ' - ' 
      || pro_crs.COL_PDS 
      || ' - ' 
      || pro_crs.COL_VOL 
      || ' - ' 
      || pro_crs.PCB 
      || ' - ' 
      || pro_crs.PDS_BRT 
      || ' - ' 
      || pro_crs.PDS_NET 
      || ' - ' 
      || pro_crs.VOL 
      || ' - ' 
      || pro_crs.COD_EAN 
      || ' - ' 
      || pro_crs.COD_TRS); 
     END LOOP; 
    END LOOP; 
END; 
/

НУ tput:

УАТ: 0080000228 данные: - 9000000026 - 500 - .25 - 138 - 110 - 4 - 1 -> Produit: 110089 про: 110089 - 500 - 400 - 250 - сухое молоко 28,8% кремового BAG 25 KG IN BULK - LOT1 - 2017-01-22T00: 00: 00 - МОЛОЧНЫЙ ПОРОШОК 28,8% КРЕМ-МЕШОК 25 КГ В БОЛКЕ. .267 - .002 - 1 - .267 - .267 - .002 - 1000 - FOURNISSEUR - > Produit: 110090 pro: 110090 - 50 - 40 - 25 - МОЛОЧНЫЙ ПОРОШОК 40% КРЕМ-МЕШКА 25 КГ - LOT2 - 2017-02-25T00: 00: 00 - МОЛОЧНЫЙ ПОРОШОК 40% КРЕМ-МЕШКА 25 КГ - .167 - .001 - 1 - .267 - .267 - .002 - 1001 - SYNUTRA UAT: 0080000229 данные: - 9000000027 - 50 - .025 - 13.8 - 11 - .4 - 1 -> Продукция: 82 pro: 82 - 5000 - 4000 - 2500 - DMU Lait non traité -interface SPX !! S2a - LOT3 - 2017-03-15T00: 00: 00 - DMU Lait non traité -interface SPX !! S2a - 16,7 - 1 - 1 - 267 - 267 - 2 - 1003 - 0000001001