oracle写xml文件,如记录过多,循环输出

最近由于工作需要,得写一个接口文件,需求如下:
 
每个XML文件中发票开具记录数量不能超过100000条,超过时分成多个XML文件;并需要严格遵守提供的文件名命名规范和XML标准内容要求。

明细文件命名规范为TAX_FPXX_日期_税务登记号_文件序号.xml(文件名字母必须大写,文件扩展名必须小写)。

汇总文件命名规范为TAX_FPXX_HZ_日期_税务登记号.xml(文件名字母必须大写,文件扩展名必须小写)。每月报送一次。

TAX_FPXX:为固定项。

日期:文件产生日期。格式为YYYYMMDD

文件序号:从1开始递增。文件产生日期下根据文件大小要求,切分的文件序号。

例如:TAX_FPXX_20140101_330201764547962_1.xml。

      TAX_FPXX_HZ_20140101_330201764547962.xml。



CREATE OR REPLACE procedure STDBA.proc_tax_upload
(v_date varchar2)
is

--------需要写两个文件,一个是汇总文件HZINFO,另一个是明细文件FPINFO----------------------

  FPINFO UTL_FILE.FILE_TYPE; --声明明细文件FPINFO
  HZINFO UTL_FILE.FILE_TYPE;--声明明细文件HZINFO
  v_temp clob; --用于写xml格式数据
  cursor c_table_info is
  select ROWNUM, WYM,FPDM,FPHM,YFPDM,YFPHM,KPRQ,FKFDM,FKFMC,FKTKZT,DBFPSL,SPHSL,SPHJJE,SJKPJE from stdba.v_tax_upload_his where substr(KPRQ,1,6)=v_date;--取明细数据


  v_wym VARCHAR2(40);
  v_fpdm VARCHAR2(12);
  v_fphm VARCHAR2(8);
  v_yfpdm VARCHAR2(12);
  v_yfphm  VARCHAR2(8);
  v_kprq VARCHAR2(8);
  v_fkfdm VARCHAR2(32);
  v_fkfmc VARCHAR2(200);
  v_fktkzt VARCHAR2(1);
  v_dbfpsl  VARCHAR2(2);
  v_sphsl  VARCHAR2(3);
  v_sphjje VARCHAR2(14);
  v_sjkpje  VARCHAR2(14);
  v_count  number;--数据总记录数
  v_total  VARCHAR2(8);
  v_uniform varchar(30);
  v_name varchar(50);
  v_tax_count  VARCHAR2(8);
  v_row number default 0; --记录循环输出行数
  v_seq number default 1;--用于写文件名
  v_list number;--用于写xml中的记录数

 


  doc       XMLDOM.DOMDOCUMENT;
  doc_node  XMLDOM.DOMNODE;
  root_node XMLDOM.DOMNODE;
  fp_node   XMLDOM.DOMNODE;
  wym_node  XMLDOM.DOMNODE;

  root_elmt XMLDOM.DOMELEMENT;
  fp_elmt   XMLDOM.DOMELEMENT;
  wym_elmt  XMLDOM.DOMELEMENT;


  tck_text  XMLDOM.DOMTEXT;

begin


 select count(*) into v_total from stdba.v_tax_upload_his where substr(KPRQ,1,6)=v_date ;

 

 select count(*) into v_count from stdba.v_tax_upload_his where substr(KPRQ,1,6)=v_date;
 


 select sum(DBFPSL) into v_tax_count from stdba.v_tax_upload_his where substr(KPRQ,1,6)=v_date;

 select uniform_no,gui_name into v_uniform,v_name from  store  where ;
 
 

  if (v_count>100000) then v_list:=100000;else v_list:=v_count; end if; --如果记录小于等于100000,则只需写一个文件,所以记录数即总的行数;如果大于100000,则第一个记录数为100000
  --xml header
  FPINFO := utl_file.fopen_nchar('DIR_TAX', 'TAX_FPXX_'||to_char(sysdate,'yyyymmdd')||'_'||v_uniform||'_'||v_seq||'.xml', 'W', 32767); --跟前面说的一样必须先创建一个directory才行
  UTL_FILE.PUT_LINE_NCHAR(FPINFO,'<?xml version="1.0" encoding="UTF-8"?>');
  UTL_FILE.PUT_LINE_NCHAR(FPINFO,''/* ''*/);
  UTL_FILE.PUT_LINE_NCHAR(FPINFO,'');
  UTL_FILE.PUT_LINE_NCHAR(FPINFO,'');
  UTL_FILE.PUT_LINE_NCHAR(FPINFO,''||v_uniform||'');
  UTL_FILE.PUT_LINE_NCHAR(FPINFO,''||v_name||'');
  UTL_FILE.PUT_LINE_NCHAR(FPINFO,'');
  UTL_FILE.PUT_LINE_NCHAR(FPINFO,'');
  UTL_FILE.FFLUSH(FPINFO); --直接写入到磁盘文件中,不会停留在内存中
  UTL_FILE.FCLOSE(FPINFO);

  open c_table_info;

  loop

    fetch c_table_info
      into v_row, v_wym, v_fpdm,v_fphm,v_yfpdm,v_yfphm,v_kprq,v_fkfdm,v_fkfmc,v_fktkzt,v_dbfpsl,v_sphsl,v_sphjje,v_sjkpje;

    exit when (c_table_info%notfound );

    --XML节点

    doc := XMLDOM.NEWDOMDOCUMENT;
    xmldom.setCharset(doc, 'UTF-8');

    doc_node := XMLDOM.MAKENODE(doc);

    root_elmt := XMLDOM.CREATEELEMENT(doc, 'FPHZXX_JL');
    root_node := XMLDOM.APPENDCHILD(doc_node, XMLDOM.MAKENODE(root_elmt));

    fp_elmt := XMLDOM.CREATEELEMENT(doc, 'FPHZXX');
    fp_node := XMLDOM.APPENDCHILD(root_node, XMLDOM.MAKENODE(fp_elmt));
    XMLDOM.setAttribute(fp_elmt, 'class','FPHZXX');

    wym_elmt := XMLDOM.CREATEELEMENT(doc, 'WYM');
    wym_node := XMLDOM.APPENDCHILD(fp_node, XMLDOM.MAKENODE(wym_elmt));
    tck_text := XMLDOM.CREATETEXTNODE(doc, v_wym);
    wym_node := XMLDOM.APPENDCHILD(wym_node, XMLDOM.MAKENODE(tck_text));

    wym_elmt := XMLDOM.CREATEELEMENT(doc, 'FPDM');
    wym_node := XMLDOM.APPENDCHILD(fp_node, XMLDOM.MAKENODE(wym_elmt));
    tck_text := XMLDOM.CREATETEXTNODE(doc, v_fpdm);
    wym_node := XMLDOM.APPENDCHILD(wym_node, XMLDOM.MAKENODE(tck_text));

    wym_elmt := XMLDOM.CREATEELEMENT(doc, 'FPHM');
    wym_node := XMLDOM.APPENDCHILD(fp_node, XMLDOM.MAKENODE(wym_elmt));
    tck_text := XMLDOM.CREATETEXTNODE(doc, v_fphm);
    wym_node := XMLDOM.APPENDCHILD(wym_node, XMLDOM.MAKENODE(tck_text));

    wym_elmt := XMLDOM.CREATEELEMENT(doc, 'YFPDM');
    wym_node := XMLDOM.APPENDCHILD(fp_node, XMLDOM.MAKENODE(wym_elmt));
    tck_text := XMLDOM.CREATETEXTNODE(doc, v_yfpdm);
    wym_node := XMLDOM.APPENDCHILD(wym_node, XMLDOM.MAKENODE(tck_text));

    wym_elmt := XMLDOM.CREATEELEMENT(doc, 'YFPHM');
    wym_node := XMLDOM.APPENDCHILD(fp_node, XMLDOM.MAKENODE(wym_elmt));
    tck_text := XMLDOM.CREATETEXTNODE(doc, v_yfphm);
    wym_node := XMLDOM.APPENDCHILD(wym_node, XMLDOM.MAKENODE(tck_text));

    wym_elmt := XMLDOM.CREATEELEMENT(doc, 'KPRQ');
    wym_node := XMLDOM.APPENDCHILD(fp_node, XMLDOM.MAKENODE(wym_elmt));
    tck_text := XMLDOM.CREATETEXTNODE(doc, v_kprq);
    wym_node := XMLDOM.APPENDCHILD(wym_node, XMLDOM.MAKENODE(tck_text));


    wym_elmt := XMLDOM.CREATEELEMENT(doc, 'FKFDM');
    wym_node := XMLDOM.APPENDCHILD(fp_node, XMLDOM.MAKENODE(wym_elmt));
    tck_text := XMLDOM.CREATETEXTNODE(doc, v_fkfdm);
    wym_node := XMLDOM.APPENDCHILD(wym_node, XMLDOM.MAKENODE(tck_text));

    wym_elmt := XMLDOM.CREATEELEMENT(doc, 'FKFMC');
    wym_node := XMLDOM.APPENDCHILD(fp_node, XMLDOM.MAKENODE(wym_elmt));
    tck_text := XMLDOM.CREATETEXTNODE(doc, v_fkfmc);
    wym_node := XMLDOM.APPENDCHILD(wym_node, XMLDOM.MAKENODE(tck_text));

    wym_elmt := XMLDOM.CREATEELEMENT(doc, 'FKTKZT');
    wym_node := XMLDOM.APPENDCHILD(fp_node, XMLDOM.MAKENODE(wym_elmt));
    tck_text := XMLDOM.CREATETEXTNODE(doc, v_fktkzt);
    wym_node := XMLDOM.APPENDCHILD(wym_node, XMLDOM.MAKENODE(tck_text));

    wym_elmt := XMLDOM.CREATEELEMENT(doc, 'DBFPSL');
    wym_node := XMLDOM.APPENDCHILD(fp_node, XMLDOM.MAKENODE(wym_elmt));
    tck_text := XMLDOM.CREATETEXTNODE(doc, v_dbfpsl);
    wym_node := XMLDOM.APPENDCHILD(wym_node, XMLDOM.MAKENODE(tck_text));

    wym_elmt := XMLDOM.CREATEELEMENT(doc, 'SPHSL');
    wym_node := XMLDOM.APPENDCHILD(fp_node, XMLDOM.MAKENODE(wym_elmt));
    tck_text := XMLDOM.CREATETEXTNODE(doc, v_sphsl);
    wym_node := XMLDOM.APPENDCHILD(wym_node, XMLDOM.MAKENODE(tck_text));

    wym_elmt := XMLDOM.CREATEELEMENT(doc, 'SPHJJE');
    wym_node := XMLDOM.APPENDCHILD(fp_node, XMLDOM.MAKENODE(wym_elmt));
    tck_text := XMLDOM.CREATETEXTNODE(doc, v_sphjje);
    wym_node := XMLDOM.APPENDCHILD(wym_node, XMLDOM.MAKENODE(tck_text));

    wym_elmt := XMLDOM.CREATEELEMENT(doc, 'SJKPJE');
    wym_node := XMLDOM.APPENDCHILD(fp_node, XMLDOM.MAKENODE(wym_elmt));
    tck_text := XMLDOM.CREATETEXTNODE(doc, v_sjkpje);
    wym_node := XMLDOM.APPENDCHILD(wym_node, XMLDOM.MAKENODE(tck_text));

    v_temp := ' ';
    --写入到临时变量v_temp中
    XMLDOM.WRITETOCLOB(doc, v_temp);

    FPINFO := utl_file.fopen_nchar('DIR_TAX', 'TAX_FPXX_'||to_char(sysdate,'yyyymmdd')||'_'||v_uniform||'_'||v_seq||'.xml', 'A', 32767); --以a模式会在文件后添加内容,用w会覆盖之前的内容

    UTL_FILE.PUT_LINE_NCHAR(FPINFO, v_temp);

    UTL_FILE.FFLUSH(FPINFO);

    UTL_FILE.FCLOSE(FPINFO);
    XMLDOM.FREEDOCUMENT(doc);
   
    v_row := v_row+1;
   
    -----------达到100000条数据时,写文件尾,并开始写新文件------------------------------
    if (mod((v_row-1),100000)=0) then 
      FPINFO := utl_file.fopen_nchar('DIR_TAX', 'TAX_FPXX_'||to_char(sysdate,'yyyymmdd')||'_'||v_uniform||'_'||v_seq||'.xml', 'a', 32767);
      --xml tail
      UTL_FILE.PUT_LINE_NCHAR(FPINFO,'');
      UTL_FILE.PUT_LINE_NCHAR(FPINFO,'');
      UTL_FILE.PUT_LINE_NCHAR(FPINFO,'');
      UTL_FILE.FFLUSH(FPINFO);
      UTL_FILE.FCLOSE(FPINFO);

      if (v_count-v_list*v_seq>100000) then v_list:=100000;else v_list:=v_count-v_list*v_seq; end if;--如果剩下的记录数仍然大于100000,则下一个文件的记录数为100000;否则记录数即剩下的记录数
      v_seq:=v_seq+1;--为新建文件,更改文件名
      FPINFO := utl_file.fopen_nchar('DIR_TAX', 'TAX_FPXX_'||to_char(sysdate,'yyyymmdd')||'_'||v_uniform||'_'||v_seq||'.xml', 'W', 32767); --跟前面说的一样必须先创建一个directory才行
      --xml head
      UTL_FILE.PUT_LINE_NCHAR(FPINFO,'<?xml version="1.0" encoding="UTF-8"?>');
      UTL_FILE.PUT_LINE_NCHAR(FPINFO,''/* ''*/);
      UTL_FILE.PUT_LINE_NCHAR(FPINFO,'');
      UTL_FILE.PUT_LINE_NCHAR(FPINFO,'');
      UTL_FILE.PUT_LINE_NCHAR(FPINFO,''||v_uniform||'');
      UTL_FILE.PUT_LINE_NCHAR(FPINFO,''||v_name||'');
      UTL_FILE.PUT_LINE_NCHAR(FPINFO,'');
      UTL_FILE.PUT_LINE_NCHAR(FPINFO,'');
      UTL_FILE.FFLUSH(FPINFO); --直接写入到磁盘文件中,不会停留在内存中
      UTL_FILE.FCLOSE(FPINFO);
    end if;           
  end loop;
  close c_table_info;
  --xml tail
  FPINFO := utl_file.fopen_nchar('DIR_TAX', 'TAX_FPXX_'||to_char(sysdate,'yyyymmdd')||'_'||v_uniform||'_'||v_seq||'.xml', 'a', 32767);
  UTL_FILE.PUT_LINE_NCHAR(FPINFO,'');
  UTL_FILE.PUT_LINE_NCHAR(FPINFO,'');
  UTL_FILE.PUT_LINE_NCHAR(FPINFO,'');
  UTL_FILE.FFLUSH(FPINFO);
  UTL_FILE.FCLOSE(FPINFO);
 
----------------------*************************************--------------------------------
----------------------*********开始写汇总文件**************-------------------------------
----------------------*************************************--------------------------------
  HZINFO := utl_file.fopen_nchar('DIR_TAX', 'TAX_FPXX_HZ_'||to_char(sysdate,'yyyymmdd')||'_'||v_uniform||'_1.xml', 'W', 32767);

  UTL_FILE.PUT_LINE_NCHAR(HZINFO,'<?xml version="1.0" encoding="UTF-8"?>');
  UTL_FILE.PUT_LINE_NCHAR(HZINFO,''/* ''*/);
  UTL_FILE.PUT_LINE_NCHAR(HZINFO,'');
  UTL_FILE.PUT_LINE_NCHAR(HZINFO,'');
  UTL_FILE.PUT_LINE_NCHAR(HZINFO,''||v_uniform||'');
  UTL_FILE.PUT_LINE_NCHAR(HZINFO,''||v_name||'');
  UTL_FILE.PUT_LINE_NCHAR(HZINFO,''||v_date||'');
  UTL_FILE.PUT_LINE_NCHAR(HZINFO,''||v_date||'');
  UTL_FILE.PUT_LINE_NCHAR(HZINFO,''||v_tax_count||'');
  UTL_FILE.PUT_LINE_NCHAR(HZINFO,'0');
  UTL_FILE.PUT_LINE_NCHAR(HZINFO,'');
  UTL_FILE.PUT_LINE_NCHAR(HZINFO,'');
  UTL_FILE.PUT_LINE_NCHAR(HZINFO,'');
  UTL_FILE.FFLUSH(HZINFO);
  UTL_FILE.FCLOSE(HZINFO);
  HZINFO := utl_file.fopen_nchar('DIR_TAX',  'TAX_FPXX_HZ_'||to_char(sysdate,'yyyymmdd')||'_'||v_uniform||'_1.xml', 'A', 32767);
  UTL_FILE.FFLUSH(HZINFO);
  UTL_FILE.FCLOSE(HZINFO);

end proc_tax_upload;
/


到这里就结束了

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26632406/viewspace-1371310/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/26632406/viewspace-1371310/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值