使用XMLType

时间:2015-04-22 10:26:37

标签: xml oracle plsql

我受到了一个xml类型过程的启发,用于解析和在表中插入数据。在我的情况下,表已经存在,一旦xml​​由外部应用程序生成,我需要在表中加载数据,所以我创建了我的程序,当我编译所有罚款但在执行时我有错误。 所以这是我在xml里面的程序。

CREATE OR REPLACE PROCEDURE dta_proc AS 
l_xml xmltype;
l_val VARCHAR2(10000) := '<root>
  <record>
  <id_localisation>8PJ</id_localisation>
  <data>
   <id_client>50C</id_client>  
      <mail>1@mail.com</mail>
      <adress>10  </adress>
      <num_tel>001</num_tel>
      <key>C</key>
     <contact>
        <name>toto</name>
        <birth>01/30/009</birth>
        <city>London</city>
      </contact>
  </data> 
  <data>
  <id_client>25C</id_client> 
      <mail>2@gmaiil.com</mail>
      <adress>20</adress>
      <num_tel>02200</num_tel>
      <key>D1</key>
      <contact>
        <name>tata</name>
        <birth>02/08/2004</birth>
        <city>Spa</city>
      </contact>
  </data> 
</record>
  <record>
  <id_localisation>ESP31</id_localisation>
  <data>
   <id_client>70D</id_client>  
        <mail>3@gmail.com</mail>
        <adress>7Bcd</adress>
        <num_tel>5555</num_tel>
        <key>D2</key>
      <contact>
        <name>titi</name>
        <birth>05/07/2014</birth>
        <city>StMarine</city>
      </contact>
  </data>
  <data>
        <id_client>10D</id_client>
        <mail>4@gmail.com</mail>
        <adress>888</adress>
        <num_tel>881.0</num_tel>
        <key>D3</key>
      <contact>
        <name>awk</name>
        <birth>05/08/1999</birth>
        <city>Bahrein</city>
      </contact>
  </data>
 </record>
 </root>';
     statut number;
     id_client varchar2(13);
     date_ev date;
     id_diff  varchar2(13);
BEGIN
     l_xml        := xmltype(l_val);

     FOR x IN
     (SELECT VALUE(p) col_val
     FROM TABLE(XMLSEQUENCE(EXTRACT(l_xml, '/begin/entry'))) p
     )
     loop

IF x.col_val.existsnode('/root/record/id_localisation//text()') > 0 THEN
         localisation := x.col_val.extract('/root/record/id_localisation//text()').getstringval();
END IF;
if x.col_val.existsnode('/root/record/data/id_client/text()') > 0 then
     id_client := x.col_val.extract('/root/record/data/id_client/text()').getstringval();
end if;
if x.col_val.existsnode('/root/record/data/num_tel/text()') > 0 then
     num_tel := x.col_val.extract('/root/record/data/num_tel/text()').getstringval();
end if;
IF x.col_val.existsnode('/root/record/data/contact/city/text()') > 0 THEN
         city := x.col_val.extract('/root/record/data/contact/city/text()').getstringval();
end if;
INSERT INTO Customer
     (
          Loca,
          ID_CLT,
          TEL,
          Town
     )
     VALUES
     (
          localisation,
          id_client,
          num_tel,
          city
     );
     localisation := null;
     id_client := null;
     num_tel := null;
     city := null;
     end loop;
commit;
end  dta_proc;

执行时出错:

执行xml_procedure;

ORA-31011: XML parsing failed
ORA-19202: Error occurred in XML processing
LPX-00245: extra data after end of document
Error at line 26
ORA-06512: at "SYS.XMLTYPE", line 310
ORA-06512: at "xml_procedure", line 58
ORA-06512: at line 1
31011. 00000 -  "XML parsing failed"
*Cause:    XML parser returned an error while trying to parse the document.
*Action:   Check if the document to be parsed is valid.

还有一个问题。生成后,如何在我的过程中自动加载xml?

1 个答案:

答案 0 :(得分:0)

我不会使用xmlsequence等来生成xmltype,而是执行以下操作(适用于11.2.0.3):

with sample_data as (select 
'<root>
  <record>
    <id_localisation>8PJ</id_localisation>
    <data>
      <id_client>50C</id_client>  
      <mail>1@mail.com</mail>
      <adress>10  </adress>
      <num_tel>001</num_tel>
      <key>C</key>
      <contact>
        <name>toto</name>
        <birth>01/30/009</birth>
        <city>London</city>
      </contact>
    </data> 
    <data>
      <id_client>25C</id_client> 
      <mail>2@gmaiil.com</mail>
      <adress>20</adress>
      <num_tel>02200</num_tel>
      <key>D1</key>
      <contact>
        <name>tata</name>
        <birth>02/08/2004</birth>
        <city>Spa</city>
      </contact>
    </data> 
  </record>
  <record>
    <id_localisation>ESP31</id_localisation>
    <data>
      <id_client>70D</id_client>  
      <mail>3@gmail.com</mail>
      <adress>7Bcd</adress>
      <num_tel>5555</num_tel>
      <key>D2</key>
      <contact>
        <name>titi</name>
        <birth>05/07/2014</birth>
        <city>StMarine</city>
      </contact>
    </data>
    <data>
      <id_client>10D</id_client>
      <mail>4@gmail.com</mail>
      <adress>888</adress>
      <num_tel>881.0</num_tel>
      <key>D3</key>
      <contact>
        <name>awk</name>
        <birth>05/08/1999</birth>
        <city>Bahrein</city>
      </contact>
    </data>
  </record>
</root>' str from dual)
-- end of mimicking your sample xml
 select x.localisation,
        y.id_client,
        y.num_tel,
        y.city
 from   sample_data sd,
        xmltable('/root/record'
                 passing xmltype(sd.str)
                 columns localisation varchar2(20) path 'id_localisation',
                         subxml xmltype path '.') x,
        xmltable('/record/data'
                 passing x.subxml
                 columns id_client varchar2(13) path 'id_client',
                         num_tel varchar2(10) path 'num_tel',
                         city varchar2(20) path 'contact/city') y;

LOCALISATION         ID_CLIENT     NUM_TEL    CITY                
-------------------- ------------- ---------- --------------------
8PJ                  50C           001        London              
8PJ                  25C           02200      Spa                 
ESP31                70D           5555       StMarine            
ESP31                10D           881.0      Bahrein             

然后,您可以在插入中使用该select语句(显然,没有WITH子句,因为您已将xml数据存储在某处(例如,传入的表或参数)。

关于自动生成xml一旦生成的负载的问题...你不能给我们提供足够的信息以便能够回答这个问题。我假设生成xml的外部应用程序需要调用您的过程来存储它,并将xml作为参数传递。