用于从Oracle数据库表生成XML文件

时间:2014-04-28 12:56:10

标签: sql xml oracle plsqldeveloper

我有一个查询我想要创建一个存储过程来生成一个带有尊重表的xml文件,存储过程输入参数是表名,当用户执行这个存储过程然后在select目录中创建了一个xml文件,我创建了一个商店的程序,但我没有得到正确的xml格式, 请帮忙

<? xml version= 1.0 encoding= utf-8 standalone= yes?>
<root xmlns xs="http //www.w3.org/2001/xmlschema"> 
<tablename> 
<column name1>column data</column name1>
<column name2>column data</column name2>
<column name3>column data</column name3>
<column name4>column data</column name4>

<column name1>column data</column name1>
<column name2>column data</column name2>
<column name3>column data</column name3>
<column name4>column data</column name4>

<column name1>column data</column name1>
<column name2>column data</column name2>
<column name3>column data</column name3>
<column name4>column data</column name4>

<column name1>column data</column name1>
<column name2>column data</column name2>
<column name3>column data</column name3>
<column name4>column data</column name4>
     ....
     ....
</tablename>


create or replace 
PROCEDURE Export_In_XML1 
(
   V_TABLE_NAME1 IN varchar2,
   v_FLAG OUT NUMBER
  )
AS
BEGIN
             ----- Export  table data
          DECLARE
            v_file  UTL_FILE.file_type;
            qryCtx DBMS_XMLGEN.ctxHandle;
            result CLOB;
            v_FILENAME varchar(50);
            xt_data xmltype;
            v_ctx dbms_xmlgen.ctxHandle;
            rc_data sys_refcursor;
            V_TABLE_NAME varchar(50);

     BEGIN
            ---------for Project table
           V_TABLE_NAME :=UPPER(V_TABLE_NAME1);    


         IF UPPER(V_TABLE_NAME) = 'LEG_DISTRICTS' THEN  

                                           BEGIN 
                                               v_file := UTL_FILE.fopen('MYXML',V_TABLE_NAME ||'.xml', 'W');

                                               OPEN rc_data FOR 
                                              'SELECT COUNTYID as COUNTYID,
                                                        ASSEMBLY,
                                                        SENATE,
                                                        CONG,
                                                        TXT_ASS,
                                                        TXT_SEN,
                                                        TXT_CON 
                                                        from '||V_TABLE_NAME ||'';

                                                  v_ctx := dbms_xmlgen.newContext (rc_data);

                                                  DBMS_XMLGEN.setrowsettag(v_ctx, 'LEG_DISTRICTS'); 
                                                  DBMS_XMLGEN.setrowtag(v_ctx, NULL);

                                                  xt_data := dbms_xmlgen.getXMLType(v_ctx);
                                                  dbms_xmlgen.closeContext (v_ctx);
                                                  v_file := UTL_FILE.fopen('MYXML', V_TABLE_NAME ||'.xml', 'A');

                                                  dbms_xslprocessor.clob2file( xt_data.getclobval( ), 'MYXML', ''||V_TABLE_NAME||'.xml',1);
                                                  v_FLAG := 1;

                                                  UTL_FILE.FCLOSE(v_file);

                                               EXCEPTION
                                                  WHEN OTHERS THEN
                                                       DBMS_OUTPUT.PUT_LINE(SQLERRM);
                                                       dbms_xmlgen.closeContext (v_ctx);
                                                        UTL_FILE.FCLOSE(v_file);
                                                        v_FLAG := 0;

                                               end ;

               ELSIF UPPER(V_TABLE_NAME) = 'EMAIL' THEN  

                                   BEGIN 
                                       v_file := UTL_FILE.fopen('MYXML',V_TABLE_NAME ||'.xml', 'W');

                                       OPEN rc_data FOR 
                                      '  SELECT SUBJECT as SUBJECT,
                                                TRIM(MESSAGE) AS MESSAGE,
                                                TRIM(SENDTO) AS SENDTO,
                                                TRIM(SENT) AS SENT,
                                                SENT_TIME,
                                                ID from '||V_TABLE_NAME ||'  ';

                                          v_ctx := dbms_xmlgen.newContext (rc_data);

                                          DBMS_XMLGEN.SETNULLHANDLING(v_ctx,0);
                                          DBMS_XMLGEN.setrowsettag(v_ctx, 'EMAIL'); 
                                          DBMS_XMLGEN.setrowtag(v_ctx, NULL);

                                          xt_data := dbms_xmlgen.getXMLType( nvl(v_ctx,''));
                                          dbms_xmlgen.closeContext (v_ctx);
                                          v_file := UTL_FILE.fopen('MYXML', V_TABLE_NAME || '.xml', 'A');

                                          dbms_xslprocessor.clob2file( xt_data.getclobval( ), 'MYXML', ''||V_TABLE_NAME||'.xml',1);
                                          v_FLAG := 1;

                                          UTL_FILE.FCLOSE(v_file);

                                       EXCEPTION
                                          WHEN OTHERS THEN
                                               DBMS_OUTPUT.PUT_LINE(SQLERRM);
                                               dbms_xmlgen.closeContext (v_ctx);
                                                UTL_FILE.FCLOSE(v_file);
                                                v_FLAG := 0;

                                       END ;
            -----for all other tables 
          ELSE


         BEGIN    
                    qryCtx :=  dbms_xmlgen.newContext ('SELECT * from '||V_TABLE_NAME ||''); 
                    v_FILENAME :=V_TABLE_NAME;
                    DBMS_XMLGEN.setMaxRows(qryCtx, 5);
                       v_file := UTL_FILE.fopen('MYXML',v_FILENAME ||'.xml', 'W');
                     UTL_FILE.put_line(v_file, '<'||v_FILENAME||'>');
                     -- v_file := UTL_FILE.FOPEN('MYXML', v_FILENAME|| '.xml', 'R');

                    LOOP
                    DBMS_XMLGEN.SETNULLHANDLING(qryCtx ,null);
                    DBMS_XMLGEN.setRowSetTag(qryCtx, 0);
                    DBMS_XMLGEN.setRowTag(qryCtx, '');

                    -- save the XML into the CLOB field
                    result :=  DBMS_XMLGEN.getXML(qryCtx);

                    result := REPLACE( result, '<?xml version="1.0"?>',' ');
                    result := REPLACE( result, '<_x0030_>',' ');
                    result := REPLACE( result, '</_x0030_>',' '); 

                    -- UTL_FILE.put_line(v_file, '');
                     EXIT WHEN DBMS_XMLGEN.getNumRowsProcessed(qryCtx) = 0; 
                        -- store the XML to a XML files
                      UTL_FILE.put_line(v_file, result);
                       END LOOP; 
                    UTL_FILE.put_line(v_file,'</'||v_FILENAME||'>');
                     UTL_FILE.FCLOSE(v_file);
             END;  


        END IF;

   END;
END Export_In_XML1;

以上商店程序给出结果

<AGNCY>

 <AGENCYID>01</AGENCYID>
 <NAME>ABC</NAME>
 <MARKDELETED>02</MARKDELETED>
 <AGENCYID>02</AGENCYID>
 <NAME>Area</NAME>
 <MARKDELETED>0</MARKDELETED>
 <AGENCYID>03</AGENCYID>
 <NAME>CTSA</NAME>
 <MARKDELETED>0</MARKDELETED>
 <AGENCYID>004</AGENCYID>
 <NAME>Glal</NAME>
 <MARKDELETED>0</MARKDELETED>
-----
-----
-----
</AGNCY>

我需要以下输出

需要输出----------

<? xml version= 1.0 encoding= utf-8 standalone= yes?>
<root xmlns xs="http //www.w3.org/2001/xmlschema"> 
<AGNCY>
 <AGENCYID>01</AGENCYID>
 <NAME>ABC</NAME>
 <MARKDELETED>02</MARKDELETED>
 <AGENCYID>02</AGENCYID>
 <NAME>Area</NAME>
 <MARKDELETED>0</MARKDELETED>

-----
-----
-----
</AGNCY>

如果,我使用UTL_FILE.put_line生成XML,那么我会丢失一些表数据..

2 个答案:

答案 0 :(得分:0)

您可以修改此行以使用前两行“必需输出”

替换默认声明
result := REPLACE( result, '<?xml version="1.0"?>',' ');

然后添加结束标记

DBMS_LOB.append(result, TO_CLOB('</root>'));

看起来您的问题不在于XML和DBMS_XMLGET,而在于如何使用CLOBS。 所以,这里有一个链接: http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_lob.htm

或许问题是你想要的输出也不是格式良好的xml?您没有关闭 root 标记。

我会保留原始答案,即使没有那么有用......

这里是您的代码(我替换了&lt;&gt; with“):

.10在文件中写“tablename”

.20列出项目

.30在clob中写表行

.40将clob写入文件

.50将“/ tablename”写入文件

我看到缺少一些步骤:

.05写“?xml ... to file

.06写“root ... to file

.55将“/ root”写入文件

答案 1 :(得分:0)

您是否尝试使用XMLSERIALIZE生成具有正确声明的CLOB,然后

SQL> desc DBMS_XSLPROCESSOR
PROCEDURE CLOB2FILE
Argument Name                  Type                    In/Out Default?
------------------------------ ----------------------- ------ --------
CL                             CLOB                    IN
FLOCATION                      VARCHAR2                IN
FNAME                          VARCHAR2                IN
CSID                           NUMBER                  IN     DEFAULT