I am trying to insert code of XML file into a column which is of XMLtype
I have below query which is working fine
select extract(xmlcol,'/*')
from (SELECT xmltype(BFILENAME('MEDIA_DIR', 'xmldata1.xml'),nls_charset_id('UTF-8')) xmlcol FROM dual)
On running this query I am getting the Xmlcode inside the xml file(xmldata1) in one row.
Now, As per my requirement I have created a type which reads data from the XMLfile. Below is the code of member function of the type:
create or replace type body t_emp
as
member function get_xml return xmltype is
v_xml xmltype;
begin
select extract(xmlcol,'/*') into v_xml
from (SELECT xmltype(BFILENAME('MEDIA_DIR', 'xmldata1.xml'),nls_charset_id('UTF-8')) xmlcol FROM dual);
return v_xml;
end get_xml;
end;
I am calling this type member function in my code. Below is the code
declare
t_emp1 t_emp;
r1 xmltype;
begin
t_emp1 := t_emp(2);
r1 := t_emp1.get_xml;
insert into EMPLOYEE_XML values (t_emp1.id,r1);
end;
Here variable r1 is of importance as I am fetching XML data in this variable. On running this code I am getting below error:
ORA-22285: non-existent directory or file for FILEOPEN operation
I am not able to understand why this error is coming as the directory exist. I am able to run previously mentioned SQL query.
Thanks!!
The user you are creating the type as only has permissions on the directory object granted through a role. Privileges from roles are not inherited by stored PL/SQL blocks by default. When you run the SQL directly the role is enabled; when you run in through the PL/SQL member function the role is disabled and the directory is not visible to your user. You need the directory privileges to be granted directly to your user.
In your case you are working in the SYSTEM
schema (so the directory privilege is coming via the EXP_FULL_DATABASE
role, which comes from DBA
), which is a bad idea; it is not good practice to create objects in that schema (or any built-in schema), so granting privileges directly to SYSTEM
would also be a mistake here.
You should create a new user/schema, with the minimum privileges it needs. You've already created the directory object, so the new user set-up would include:
grant read,write on directory media_dir to your_new_user;
You can then create the type and its member function in that new schema, and you'll be able to execute it from your anonymous block.
If you can only have privileges granted through a role then you could instead change the type declaration to use invoker's rights
create or replace type t_emp authid current_user as object ...
That would even work in your current scenario, sticking with SYSTEM
; but again you really shouldn't be working in that schema.