首页 > 解决方案 > 使用没有命名目录的 dbms_xmldom.writetofile

问题描述

我正在尝试使用过程使用 PL/SQL 编写 XML 文件dbms_xmldom.writetofile。但是,上面的代码仅在我提供取自DBA_DIRECTORIES如下所示的命名目录时才有效:

procedure PRINT_XML (p_xml          xmltype
                    ,p_requestid    number)
is

    l_filename      varchar2(100);
    doc             dbms_xmldom.domdocument;
    l_directory     request_history.OUTPUTWORKDIRECTORY%type;
    l_dml_stmnt     request_history.OUTPUTWORKDIRECTORY%type;

begin

    l_filename          := 'JPK_Accounting_Books_'||g_jpk_ess_request_id||'.xml';
    
    doc := dbms_xmldom.newdomdocument(p_xml);
    dbms_xmldom.writetofile(doc, 'TMP/'||l_filename);
    dbms_xmldom.freeDocument(doc);

EXCEPTION
    WHEN OTHERS THEN
        write_to_aflog(p_module     => 'JG.JPK.JE_PL_JPK_ACCT_BOOKS.PRINT_XML'
                  ,    p_message    => 'Error in PRINT_XML '||sqlerrm);
        raise;
end PRINT_XML;

我希望以编程方式提供目录,因为每次执行都会更改目录,如下所示:

procedure PRINT_XML (p_xml          xmltype
                    ,p_requestid    number)
is

    l_filename      varchar2(100);
    doc             dbms_xmldom.domdocument;
    l_directory     request_history.OUTPUTWORKDIRECTORY%type;
    l_dml_stmnt     request_history.OUTPUTWORKDIRECTORY%type;

begin

    l_filename          := 'JPK_Accounting_Books_'||g_jpk_ess_request_id||'.xml';
    
    select  OUTPUTWORKDIRECTORY
    into    l_directory
    from    request_history -- ESS
    where   requestid = p_requestid;
        
    doc := dbms_xmldom.newdomdocument(p_xml);
    dbms_xmldom.writetofile(doc, l_directory||'/'||l_filename);
    dbms_xmldom.freeDocument(doc);

EXCEPTION
    WHEN OTHERS THEN
        write_to_aflog(p_module     => 'JG.JPK.JE_PL_JPK_ACCT_BOOKS.PRINT_XML'
                  ,    p_message    => 'Error in PRINT_XML '||sqlerrm);
        raise;
end PRINT_XML;

但是,我收到一个错误ORA-29280: invalid directory path。我试图做一个,EXECUTE IMMEDIATE CREATE OR REPLACE DIRECTORY...但我得到:ORA-01031: insufficient privileges

由于组织的政策,我无法执行以下操作:

  1. 添加另一个永久目录DBA_DIRECTORIES
  2. 为当前用户提供额外的权限

有没有另一种方法来使用 dbms_xmldom.writetofile (或类似的东西)而不创建命名目录?

标签: sqlxmldatabaseoracleplsql

解决方案


第一个问题是路径可能不存在,或者您对该目录没有写权限。

SQL> select directory_path from all_directories where directory_name = 'YOUR DIRECTORY' ;

如果没有行,则需要通过 DBA 解决此问题,因为该目录不存在或您对其没有权限。数据库目录是两个元素的组合:

  • 数据库目录是操作系统中某个位置的指针或引用。
  • 该目录的路径必须存在,并且运行该进程的用户必须拥有对该目录的读写权限。

对于第二个问题,问题是拥有该过程的用户没有被授予系统特权 CREATE ANY DIRECTORY。您的 DBA 必须授予对您的用户的 CREATE ANY DIRECTORY 特权,尽管我不推荐这样做。授予 ANY 权限是一种不好的安全做法。

创建目录通常是 DBA 的任务。只要您还必须根据您的操作系统在文件系统 ( Linux ) 或 Windows 驱动器中创建底层目录,我预计不会出现需要动态创建它们的情况。

鉴于您的特殊情况,您别无选择。您需要重新评估解决方案。也许您可能会使用 WRITETOCLOB 而不是 WRITETOFILE ,然后通过 sqlplus 在您的客户端假脱机结果


推荐阅读