3

我正在尝试使用以下代码使用 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

我做错了什么。

4

1 回答 1

4

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

DBMS_XMLDOM文件指出

注意:数据库启动前,必须指定init.ORA文件中的read-from和write-to目录;例如: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.
于 2013-04-03T23:02:32.193 回答