Use dbms_xmldom.writetofile without a Named Directory

不问归期 提交于 2021-01-29 05:30:53

问题


I am trying to write an XML file using PL/SQL using the procedure dbms_xmldom.writetofile. However, the code above only works when I supply a named directory taken from DBA_DIRECTORIES like below:

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;

I was hoping to supply the directory programmatically, as the directory changes per execution, like below:

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;

However, i am getting an error ORA-29280: invalid directory path. I have tried to do an EXECUTE IMMEDIATE CREATE OR REPLACE DIRECTORY... but i am getting: ORA-01031: insufficient privileges.

I cannot do the following due to the organization's policies:

  1. Add another permanent directory in DBA_DIRECTORIES
  2. Provide additional privileges to the current user

Is there another way to use dbms_xmldom.writetofile (or something similar) without creating a named directory?


回答1:


The first issue is that probably the path does not exist or you have no write privileges over the directory.

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

If you got no rows, you need to address this with your DBA, as either the directory does not exist or you have no privileges over it. A database directory is a combination of two elements:

  • The database directory is a pointer or reference to a location in the operating system.
  • The path of that directory must exist and the user who runs the process must possess read and write privileges on it.

For the second issue, the problem is that the user who owns the procedure has not been granted with the system privilege CREATE ANY DIRECTORY. Your DBA must grant the CREATE ANY DIRECTORY privilege over your user, although I don't recommend it. Granting ANY privileges is a bad security practice.

Creating directories is normally a task for your DBA. I don't foresee a scenario when you need to create them dynamically, as long as you have also to create the underlying directory in the Filesystem ( Linux ) or Windows drive, depending of your operating system.

Given your special circumstances, you have no option with this. You need to reevaluate the solution. Perhaps you might use WRITETOCLOB instead of WRITETOFILE , then spool the result in your client side by sqlplus instead



来源:https://stackoverflow.com/questions/62573615/use-dbms-xmldom-writetofile-without-a-named-directory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!