ORA-29283: invalid file operation ORA-06512: at "SYS.UTL_FILE", line 536 - oracle

Below is the code i use to extract data from a table to a flat file.
BEGIN
DECLARE
file_name VARCHAR2(50);
file_handle utl_file.file_type;
BEGIN
file_name := 'table.txt';
file_handle := utl_file.fopen('SEND',file_name,'W');
FOR rec in(
SELECT column 1
||'~'||column 2
||'~'||column 3 out_line
FROM table1)LOOP
UTL_FILE.PUT_LINE(file_handle,rec.out_line);
UTL_FILE.FFLUSH(file_handle);
END LOOP;
UTL_FILE.FCLOSE(file_handle);
END;
end;
This code is working fine in our development database but its throwing the below error if i execute in a new DB.
Error starting at line 1 in command:
BEGIN
DECLARE
file_name VARCHAR2(50);
file_handle utl_file.file_type;
BEGIN
file_name := 'table.txt';
file_handle := utl_file.fopen('SEND',file_name,'W');
FOR rec in(
SELECT column 1
||'~'||column 2
||'~'||column 3 out_line
FROM table1)LOOP
UTL_FILE.PUT_LINE(file_handle,rec.out_line);
UTL_FILE.FFLUSH(file_handle);
END LOOP;
UTL_FILE.FCLOSE(file_handle);
END;
end;
Error report:
ORA-29283: invalid file operation
ORA-06512: at "SYS.UTL_FILE", line 536
ORA-29283: invalid file operation
ORA-06512: at line 7
29283. 00000 - "invalid file operation"
*Cause: An attempt was made to read from a file or directory that does
not exist, or file or directory access was denied by the
operating system.
*Action: Verify file and directory access privileges on the file system,
and if reading, verify that the file exists.
Oracle directory 'SEND' points to some UNIX directory which has rights as
'rwxrwsr-x' (Octal 2775)
Oracle Version:11g
Please help me to solve this issue.
Guys please do let me know if you require more data from me to solve this question.

So, #Vivek has got the solution to the problem through a dialogue in the Comments rather than through an actual answer.
"The file is being created by user oracle just noticed this in our development database. i'm getting this error because, the directory where i try to create the file doesn't have write access for others and user oracle comes under others category. "
In the absence of an accepted answer to this question I proffer a link to an answer of mine on the topic of UTL_FILE.FOPEN(). Find it here.
P.S. I'm marking this answer Community Wiki, because it's not a proper answer to this question, just a redirect to somewhere else.

Assume file is already created in the predefined directory with name "table.txt"
1) change the ownership for file :
sudo chown username:username table.txt
2) change the mode of the file
sudo chmod 777 table.txt
Now, try it should work!

On Windows also check whether the file is not encrypted using EFS. I had the same problem untill I decrypted the file manualy.

I had been facing this problem for two days and I found that the directory you create in Oracle also needs to created first on your physical disk.
I didn't find this point mentioned anywhere i tried to look up the solution to this.
Example
If you created a directory, let's say, 'DB_DIR'.
CREATE OR REPLACE DIRECTORY DB_DIR AS 'E:\DB_WORKS';
Then you need to ensure that DB_WORKS exists in your E:\ drive and also file system level Read/Write permissions are available to the Oracle process.
My understanding of UTL_FILE from my experiences is given below for this kind of operation.
UTL_FILE is an object under SYS user. GRANT EXECUTE ON SYS.UTL_FILE TO
PUBLIC; needs to given while logged in as SYS. Otherwise, it will
give declaration error in procedure. Anyone can create a directory as
shown:- CREATE OR REPLACE DIRECTORY DB_DIR AS 'E:\DBWORKS'; But CREATE
DIRECTORY permission should be in place. This can be granted as
shown:- GRANT CREATE ALL DIRECTORY TO user; while logged in as SYS
user. However, if this needs to be used by another user, grants need
to be given to that user otherwise it will throw error. GRANT READ,
WRITE, EXECUTE ON DB_DIR TO user; while loggedin as the user who
created the directory. Then, compile your package. Before executing
the procedure, ensure that the Directory exists physically on your
Disk. Otherwise it will throw 'Invalid File Operation' error. (V.
IMPORTANT) Ensure that Filesystem level Read/Write permissions are in
place for the Oracle process. This is separate from the DB level
permissions granted.(V. IMPORTANT) Execute procedure. File should get
populated with the result set of your query.

The ORA-29283: invalid file operation is also raised on utl_file.put if there is an attempt to write line longer than max_linesize in text mode. max_linesize is optional 4th parameter of utl_file.fopen function defaulting to 1024.
(My case was dumping CSV from within Oracle in Docker into file in host directory mapped as Docker volume and I was misleaded by this error for pretty significat time - I seeked cause in filesystem rights or volume mapping between Docker and host, actually it was so stupid cause.)
UPDATE: another occurence of same exception also happened on utl_file.fopen. The database rejected to create file even if the file did not exist before. The directory in which the attempt of file creation happened was mapped on Docker volume. It started to work if the zero-sized file was created on host machine in advance. Attempt to create file from within container (touch /dir/file) failed though. Perhaps some docker issue - it disappeared after restarting Docker Desktop.

You need give permission by creating folder.
create or replace directory DINESH as '/home/oracle/DINESH/';
grant read, write
on directory DINESH
to public;
Simple PLSQL to open a file,
-- write two lines into the file,
-- and close the file
declare
fhandle utl_file.file_type;
begin
fhandle := utl_file.fopen(
'DINESH' -- File location
, 'test_file.txt' -- File name
, 'w' -- Open mode: w = write.
);
utl_file.put(fhandle, 'Hello world!'|| CHR(10));
utl_file.put(fhandle, 'Hello again!');
utl_file.fclose(fhandle);
exception
when others then
dbms_output.put_line('ERROR: ' || SQLCODE || ' - ' || SQLERRM);
raise;
end;
test_file.txt file created in /home/oracle/DINESH.

Related

Oracle DATAPUMP import failed

I am currently trying to import a database using DBMS_DATAPUMP in PL/SQL using the following script.
DECLARE
h1 NUMBER;
BEGIN
h1 := DBMS_DATAPUMP.OPEN('IMPORT', 'FULL', NULL, DBMS_SCHEDULER.generate_job_name, 'LATEST');
DBMS_DATAPUMP.ADD_FILE(handle => h1, filename => 'EXAMPLE6.DMP', directory => 'DUMP');
DBMS_DATAPUMP.START_JOB(h1);
dbms_datapump.detach(h1);
END;
/
Everytime I execute this code, I get the following error message.
ERROR in line 1:
ORA-39001: invalid argument value
ORA-06512: in "SYS.DBMS_SYS_ERROR", line 79
ORA-06512: in "SYS.DBMS_DATAPUMP", line 4929
ORA-06512: in "SYS.DBMS_DATAPUMP", line 5180
ORA-06512: in line 5
I already googled the error, but the answer mostly consisted of checking if the directory was already created and if the user had read and write access to the directory.
I also tried the impdp tool just as an experiment, to see if I could execute imports that way.
impdp pdb2 directory="DUMP" dumpfile="EXAMPLE6.DMP"
Based on the user I am executing impdp as, I get different error messages.
As a user with all privileges granted:
ORA-39001: invalid argument value
ORA-39000: bad dump file specification
ORA-39155: error expanding dump file name "C:\Users\...\EXAMPLE6.DMP"
ORA-48128: opening of a symbolic link is disallowed
As the sysdba user:
ORA-39002: invalid operation
ORA-39070: unable to open the log file
ORA-39087: directory name DUMP is invalid
As I already said, the directory does exist on my drive, I created the directory called DUMP in Oracle and granted read and write access to my user.
All help would be appreciated and I would be happy to clarify if I wrote something confusing!
Edit:
Output of select directory_name, directory_path from dba_directories;
DIRECTORY_NAME
--------------------------------------------------------------------------------
DIRECTORY_PATH
--------------------------------------------------------------------------------
DUMP
C:\Users\Nemanja\Desktop\oraclePLS
I forgot to mention, that the Oracle service has complete access to the specified Windows directory.

plsql CSV file reading and write

OWNER SYS
DIRECTORY_NAME ME
DIRECTORY_PATH \\172.16.20.11\Mad\
begin
vSFile := utl_file.fopen('ME','20170405.csv','R');
IF utl_file.is_open(vSFile) THEN
LOOP
i am getting error :
ORA-29283: invalid file operation ORA-06512: at "SYS.UTL_FILE", line 536 ORA-29283: invalid file operation ORA-06512: at "MADHUR.MSP_UPD_DAILYSALESFRMSAP", line 28 ORA-06512: at line 1
29283. 00000 - "invalid file operation"
*Cause: An attempt was made to read from a file or directory that does
not exist, or file or directory access was denied by the
operating system.
*Action: Verify file and directory access privileges on the file system,
and if reading, verify that the file exists.
Your error tells you exactly what the problem is:
*Cause: An attempt was made to read from a file or directory that does
not exist, or file or directory access was denied by the
operating system.
and what to do to fix it:
*Action: Verify file and directory access privileges on the file system,
and if reading, verify that the file exists.
So you specify:
DIRECTORY_PATH \\172.16.20.11\Mad\
are you able to actually access \\172.16.20.11\Mad\ with your oracle user?
if not, then you need to grant read, write on directory to user and also check OS permissions for your user to that path.
but also consider doing a network share to drive letter, instead of UNC path.
The reason for getting such issue is that you dont have read or write permission to the directory.
Run the below query to see if you have read and write priviledges:
SELECT *
FROM all_tab_privs
WHERE table_name = 'your_directory name';
If you find dont have any access then grant read and write privs.
SQL>CREATE OR REPLACE DIRECTORY dir1 as '/opt/oracle/';
SQL>GRANT READ,WRITE on dir1 to <Required user>; (if you want to give access to particular user)
OR
SQL>GRANT READ,WRITE on dir1 to PUBLIC; (if you want to give access to all users then give access to public)

I want to run this code on oracle 10g but it gives me an error

When I run this it gives me the error
ORA-00911: invalid character
CREATE OR REPLACE DIRECTORY CDATA AS 'D:\';
GRANT READ ON DIRECTORY CDATA TO PUBLIC;
DECLARE
MYFILE UTL_FILE.FILE_TYPE;
type array IS VARRAY(10) OF INTEGER;
arr array;
temp number;
curr number;
prev number;
n number;
BEGIN
MYFILE := UTL_FILE.FOPEN('CDATA','FILING.txt','W');
arr := array(98, 97, 78, 87, 92, 33, 12, 45, 45, 66);
n:= arr.count;
UTL_FILE.PUT(MYFILE, 'ORGANIZED DATA: ');
for i in 2..arr.count loop
curr:=i;
prev:=i-1;
while arr(prev) > arr(curr) loop
temp:= arr(curr);
arr(curr):= arr(prev);
arr(prev):= temp;
curr:= curr-1;
prev:= prev-1;
IF curr=1 THEN
EXIT;
END IF;
end loop;
end loop;
for i in 1.. arr.count loop
UTL_FILE.PUT_LINE(MYFILE, arr(i));
dbms_output.put_line(arr(i));
end loop;
UTL_FILE.FCLOSE(MYFILE);
END; //ORA-00911: invalid character
// File is not writting
Unable to write sorted data into file from insertion algorithm
I ran your query as a normal (public) user. There was no error as ORA-00911: invalid character. There was another error, which is expected as per the code you are running. When I ran your script as a dba user, there was no error at all.
First Approach: As a public user, you would get first error as
"insufficient privileges"
when the create directory line executes. Then you would get
"directory does not exist"
when the plsql script executes.
This is because, the directory creation and grant script have to run with dba privilege (it is a privilege that user account like 'sys' possess). The rest of the script i.e. that plsql block can run from a public user. As normal user does not have directory creation and grant privilege, hence the error.
Now, if you move directory creation to grant lines to run with a dba user, they will run fine, the above 2 errors would be gone. Then when you run the plsql block with a public user, there will be a third error
"directory access denied"
. This is because, in your grant script you have given read access on the directory object to public, while in your plsql block you are actually writing to it. To handle that, modify grant script to -
GRANT READ,WRITE ON DIRECTORY CDATA TO PUBLIC;
Second Approach
You can run the whole script including the plsql block using a dba user, where your script would encounter no errors at all.
I would suggest the best approach would be to run directory creation and grant script from a dba user and then run the plsql block from a normal nondba user, with the grant script modified as above.

Writing a file to a custom created directory on Oracle Amazon-RDS

I can connect to the database via sqlplus
sqlplus stepdba/<password>#steprds.<rds-hash-here>.<region>.rds.amazonaws.com:1521/STEP
and I am trying to write to a file.
According to AmazonRDS documentation regarding Oracle, create directory must be done with rdsadmin.rdsadmin_util.create_directory('MY_DIR'); which I have done.
To write to a file, I do the following:
DECLARE
fileHandler UTL_FILE.FILE_TYPE;
BEGIN
fileHandler := UTL_FILE.FOPEN('MY_DIR', 'test.txt', 'W');
UTL_FILE.PUTF(fileHandler, 'Writing TO a file\n');
UTL_FILE.FCLOSE(fileHandler);
END;
/
Which result in an error:
ERROR at line 1:
ORA-29283: invalid file operation
ORA-06512: at "SYS.UTL_FILE", line 536
ORA-29283: invalid file operation
ORA-06512: at line 4
If I try to write to an Oracle provided directory DATA_PUMP_DIR, the above snippet executes correctly and the file is written.
The privileges to the two directories are the same
select grantee, privilege from dba_tab_privs where table_name='DATA_PUMP_DIR' and grantee = 'STEPDBA';
select grantee, privilege from dba_tab_privs where table_name='MY_DIR' and grantee = 'STEPDBA';
In the Amazon-RDS case, we can not manipulate the file/directory permissions on the OS level.
I seem to be missing something, any hint would be appreciated.
Hi I had exactly the same problem. Solved it by using higher version of Oracle software: Oracle SE One 11.2.0.4.v4
One that was causing the problems was Oracle SE One 11.2.0.4.v3

Cannot open file using dbms_lob.filopen but can open it using utl_file

What could cause the following behaviour:
Database 11gR2
declare
l_amt number := dbms_lob.lobmaxsize;
l_dst_loc clob;
l_dst_offset number := 1;
l_lang_ctx number := dbms_lob.default_lang_ctx;
l_src_loc bfile;
l_src_offset number := 1;
l_warning number;
begin
l_src_loc := bfilename('ODS_SERVER_DIRECTORY', '_CIVKD_ASU.CSV');
dbms_lob.createtemporary(l_dst_loc, true);
dbms_lob.fileopen(l_src_loc, dbms_lob.file_readonly);
dbms_lob.loadclobfromfile(l_dst_loc
,l_src_loc
,l_amt
,l_dst_offset
,l_src_offset
,dbms_lob.default_csid
,l_lang_ctx
,l_warning);
commit;
dbms_lob.fileclose(l_src_loc);
dbms_output.put_line(substr(l_dst_loc, 1, 200));
end;
/
ORA-22288: file or LOB operation FILEOPEN failed
.
ORA-06512: in "SYS.DBMS_LOB", line 805
ORA-06512: in line 31
22288. 00000 - "file or LOB operation %s failed\n%s"
*Cause: The operation attempted on the file or LOB failed.
*Action: See the next error message in the error stack for more detailed
information. Also, verify that the file or LOB exists and that
the necessary privileges are set for the specified operation. If
the error still persists, report the error to the DBA.
However opening and reading the exact same file succeeds when using utl_file.
declare
l_file utl_file.file_type;
l_regel varchar2(4000);
begin
l_file := utl_file.fopen('ODS_SERVER_DIRECTORY', '_CIVKD_ASU.CSV', 'R');
-- Haal de volgende regel op
utl_file.get_line(l_file, l_regel);
dbms_output.put_line(l_regel);
utl_file.fclose_all;
end;
So it seems the file is available and accessable by the database.
It's the first time we run into this particular error and it's one of the first 11gR2 instances so maybe there is something 11g specific we don't know about?
=== Update 8-6-2012 ===
Some progress made. It turns out the directory object points to a shared drive. It's a windows server and Oracle runs as Local System. I always thought that it was impossible to read anything from a shared drive in this situation. Apparently in some situations you can using utl_file but not usign dbms_lob.
Could you confirm that ODS_SERVER_DIRECTORY is an actual DIRECTORY
SELECT
*
FROM
dba_objects
WHERE
object_type = 'DIRECTORY'
AND object_name = 'ODS_SERVER_DIRECTORY'
Possibly you have it set in the UTL_FILE_DIR parameter of init.ora (should not be done anymore..)
But its one possibility as to why utl_file would see the directory and dbms_lob would not.

Resources