制作XML文件时收到PL / SQL错误

时间:2013-04-03 22:20:18

标签: sql xml plsql oracle11g plsqldeveloper

我正在尝试使用以下代码使用PL / SQL过程创建XML文件: -

create or replace directory temp_dir as 'C:\XML';
grant read, write on directory temp_dir to hr;

DECLARE
      doc  DBMS_XMLDOM.DOMDocument;
      xdata  XMLTYPE;

      CURSOR xmlcur IS
      SELECT xmlelement("Employee",XMLAttributes('http://www.w3.org/2001/XMLSchema' AS "xmlns:xsi",
                                    'http://www.oracle.com/Employee.xsd' AS "xsi:nonamespaceSchemaLocation")
                                ,xmlelement("EmployeeNumber",e.employee_id)
                                ,xmlelement("EmployeeName",e.first_name)
                               ,xmlelement("Department",xmlelement("DepartmentName",d.department_name)
                                                       ,xmlelement("Location",d.location_id)
                                          )
                    )
      FROM   employees e
      ,departments d
     WHERE  e.department_id=d.department_id;

   BEGIN
     OPEN xmlcur;
     FETCH xmlcur INTO xdata;
     CLOSE xmlcur;
     doc := DBMS_XMLDOM.NewDOMDocument(xdata);
     DBMS_XMLDOM.WRITETOFILE(doc, 'temp_dir/myXML1.xml');
     EXCEPTION
    WHEN OTHERS THEN
      RAISE_APPLICATION_ERROR(-20002,'Error writing out XML.');
   END;

但我收到以下错误: -

Line 185: ORA-29280: invalid directory path
ORA-06512: at "SYS.UTL_FILE", line 41
ORA-06512: at "SYS.UTL_FILE", line 478
ORA-06512: at "XDB.DBMS_XSLPROCESSOR", line 217
ORA-29280: invalid directory path
ORA-29280: invalid directory path
ORA-06512: at "XDB.DBMS_XMLDOM", line 5292
ORA-06512: at line 23

我做错了什么。

1 个答案:

答案 0 :(得分:3)

首先,您正在尝试写入数据库服务器上的文件,对吗?客户端计算机上没有文件? c:\xml似乎是客户端计算机上可能存在的目录,而不是服务器上的目录。

DBMS_XMLDOM documentation

  

注意:在数据库启动之前,读取和写入目录   在init.ORA文件中必须指定;例如:   UTL_FILE_DIR = / mypath中/ insidemypath。

     

读取和写入文件必须位于服务器文件系统上。

似乎DBMS_XMLDOM不支持目录对象。它似乎依赖于旧的UTL_FILE_DIR参数。

就个人而言,我可能会使用getClobVal()方法将XMLType转换为CLOB,然后使用clob2file包中的DBMS_XSLPROCESSOR过程将其写出来

DBMS_XSLProcessor.Clob2File( 
  xdata.getClobVal(),
  'TEMP_DIR',
  'myXML1.xml' );

适用于我的系统

SQL> ed
Wrote file afiedt.buf

  1  DECLARE
  2    xdata  XMLTYPE;
  3    CURSOR xmlcur IS
  4    SELECT xmlelement("Employee",
  5                      XMLAttributes('http://www.w3.org/2001/XMLSchema' AS "xmlns:xsi",
  6                                    'http://www.oracle.com/Employee.xsd' AS "xsi:nonamespaceSchemaLocation")
  7                     ,xmlelement("EmployeeNumber",e.employee_id)
  8                     ,xmlelement("EmployeeName",e.first_name)
  9                     ,xmlelement("Department",
 10                                 xmlelement("DepartmentName",d.department_name)
 11                                ,xmlelement("Location",d.location_id)
 12                                )
 13                      )
 14    FROM   employees e
 15          ,departments d
 16    WHERE  e.department_id=d.department_id;
 17  BEGIN
 18    OPEN xmlcur;
 19    FETCH xmlcur INTO xdata;
 20    CLOSE xmlcur;
 21    DBMS_XSLProcessor.Clob2File(
 22        xdata.getClobVal(),
 23        'TEMP_DIR',
 24        'myXML1.xml' );
 25*    END;
SQL> /

PL/SQL procedure successfully completed.

如果你真的想从光标而不是第一行获取所有数据,你需要一个循环

SQL> ed
Wrote file afiedt.buf

  1  DECLARE
  2    xdata  XMLTYPE;
  3    CURSOR xmlcur IS
  4    SELECT xmlelement("Employee",
  5                      XMLAttributes('http://www.w3.org/2001/XMLSchema' AS "xmlns:xsi",
  6                                    'http://www.oracle.com/Employee.xsd' AS "xsi:nonamespaceSchemaLocation")
  7                     ,xmlelement("EmployeeNumber",e.employee_id)
  8                     ,xmlelement("EmployeeName",e.first_name)
  9                     ,xmlelement("Department",
 10                                 xmlelement("DepartmentName",d.department_name)
 11                                ,xmlelement("Location",d.location_id)
 12                                )
 13                      )
 14    FROM   employees e
 15          ,departments d
 16    WHERE  e.department_id=d.department_id;
 17    l_clob clob;
 18  BEGIN
 19    dbms_lob.createtemporary( l_clob, true );
 20    OPEN xmlcur;
 21    LOOP
 22      FETCH xmlcur INTO xdata;
 23      EXIT WHEN xmlcur%notfound;
 24      l_clob := l_clob || xdata.getClobVal();
 25    END LOOP;
 26    DBMS_XSLProcessor.Clob2File(
 27      l_clob,
 28      'TEMP_DIR',
 29      'myXML1.xml' );
 30    CLOSE xmlcur;
 31* END;
SQL> /

PL/SQL procedure successfully completed.