0

We're getting the following error in an SQL procedure on Ubuntu. The same procedure is executing properly on Windows. The goal of the procedure is to import a .csv file into an external oracle table.

The Oracle error:

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

This SO question might have been a solution, but even after giving proper permissions chmod 777 (which solved the issue in that case) to the files concerned we are facing the same error.

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

The concerned portion of the procedure is :

for i in c loop   
    dbms_output.put_line('Inside for loop');
    select count(file_name) into f_n from t_filenames_exp e where i.file_name=e.file_name;
    if f_n=0 then
        dbms_output.put_line('Inside if statement');
        insert into t_filenames_exp(file_name,status) values(i.file_name,'need_to_read');
        select f_id into f_idn from t_filenames_exp e where e.file_name=i.file_name;
        select substr(i.file_name,instr(i.file_name,'exp_'),4) into fchk from dual;
        select to_char(to_date(to_char(SEQ_DATE,'dd-MON-yyyy'),'dd-MON-yyyy'),'D') into v_sufix from M_LAB_ID_SEQ_TAB;
        if(fchk='exp_') then
              file_handle := UTL_FILE.FOPEN('EXP_DATA',i.file_name,'R');
              file_handle1 := UTL_FILE.FOPEN('EXP','staging.txt','W');
            loop
                begin
                   utl_file.get_line(file_handle,output_line);
                   utl_file.put_line(file_handle1,output_line);  
                   exception when no_data_found then
                    exit;
                end;  
            end loop;

            if utl_file.is_open(file_handle) then
               utl_file.fclose(file_handle);
            end if;

            if utl_file.is_open(file_handle1) then
               utl_file.fclose(file_handle1);
            end if;  

               /*insert into  t_files_data_exp(f_id,patient_last_name,patient_name,patient_id_code,method_internal_index,method_acronym,index_repeat,result,unit_of_measurement,minimum_reference_value,maximum_reference_value,date_)
               select f_idn,patient_last_name,patient_name,(patient_id_code ||'H'||v_sufix),method_internal_index,method_acronym,index_repeat,result,  unit_of_measurement,minimum_reference_value,maximum_reference_value,date_ from files_data;*/
               insert into  t_files_data_exp(f_id,patient_last_name,patient_name,patient_id_code,method_internal_index,method_acronym,index_repeat,result,unit_of_measurement,minimum_reference_value,maximum_reference_value,date_)
                select f_idn,'Unknown','Unknown',(r.patient_id_code ||'H'||v_sufix),m.CANONICAL_ID,r.METHOD_ACRONYM,0,r.RESULT,r.unit_of_measurement,'','','' from files_data r ,M_METHODS_EXP m where m.METHOD_ACRONYM=r.METHOD_ACRONYM;

        else  
           file_handle := UTL_FILE.FOPEN('EXP_DATA',i.file_name,'R');
           file_handle1 := UTL_FILE.FOPEN('EXP','staging1.txt','W');
            loop
                begin
                   utl_file.get_line(file_handle,output_line);
                   utl_file.put_line(file_handle1,output_line);
                     exception when no_data_found then
                      exit;
                end;  
            end loop;

            if utl_file.is_open(file_handle) then
               utl_file.fclose(file_handle);
            end if;

            if utl_file.is_open(file_handle1) then
               utl_file.fclose(file_handle1);
            end if;
                 insert into  t_files_data_exp(f_id,patient_last_name,patient_name,patient_id_code,method_internal_index,method_acronym,index_repeat,result,unit_of_measurement,minimum_reference_value,maximum_reference_value,date_)  
                 select f_idn,'Unknown','Unknown',r.PATIENT_ID_CODE,m.CANONICAL_ID,r.METHOD_ACRONYM,0,r.RESULT,r.unit_of_measurement,'','','' from rfiles_data r ,M_METHODS_EXP m where m.METHOD_ACRONYM=r.METHOD_ACRONYM;                 
        end if;          
       -- Check whether the data in csv file is same as data in external table.         
        if trace='on' then
            if(fchk='expr_')  then    
              dbms_output.put_line('**************************************************');
              select i.file_name,count(*) into filename,rows_in_file from files_data;
              dbms_output.put_line('File name :'||filename);
              dbms_output.put_line('Total no of rows :'||rows_in_file);
              select replace(filename,'exp','_exp')  into new_filename from dual;       
              file_handle2 := UTL_FILE.FOPEN('EXP_LOG',new_filename,'W');
                for i1 in cur loop                      
                  /*data:=to_char (i1.patient_last_name||';'||i1.patient_name||';'||i1.patient_id_code||';'||i1.method_internal_index||';'||i1.method_acronym||';'||i1.index_repeat||';'||i1.result||';'||i1.unit_of_measurement||';'||i1.minimum_reference_value||';'||i1.maximum_reference_value||';'||i1.date_);*/

                  data:=to_char(i1.patient_id_code||';'||i1.method_acronym||';'||i1.result||';'||i1.unit_of_measurement);
                  utl_file.put_line(file_handle2,data);
                end loop;  
            else
                dbms_output.put_line('**************************************************');
                select i.file_name,count(*) into filename,rows_in_file from rfiles_data;
                dbms_output.put_line('File name :'||filename);
                dbms_output.put_line('Total no of rows :'||rows_in_file);
                select replace(filename,'expr','_expr')  into new_filename from dual;         
                file_handle2 := UTL_FILE.FOPEN('EXP_LOG',new_filename,'W');     
                for i1 in cur1 loop                      
                   /*data:=to_char (i1.m_id||';'||i1.date_||';'||i1.METHOD_ACRONYM||';'||i1.PATIENT_ID_CODE||';'||i1.TEST_TYPE||';'||i1.UNIT_OF_MEASUREMENT||';'||i1.RESULT||';'||i1.RESULT_FLAG); */
                   data:=to_char(i1.patient_id_code||';'||i1.method_acronym||';'||i1.result||';'||i1.unit_of_measurement);
                 utl_file.put_line(file_handle2,data);
                end loop;  
            end if;

            if utl_file.is_open(file_handle2) then
              utl_file.fclose(file_handle2);
            end if;         
               dbms_output.put_line('*************************************************');

        end if;

    end if;   
  end loop; 

The line on which the error is occurring is:

file_handle := UTL_FILE.FOPEN('EXP_DATA',i.file_name,'R');

The permissions given to the file is as follows:

-rwxrwxrwx 1 rama rama 240 Feb 26 11:24 exp_41_02_2016.csv`

How to trace the problem which is causing this issue? Please let me know if you want any other information?

Wyck
  • 10,311
  • 6
  • 39
  • 60
Br. Sayan
  • 486
  • 1
  • 7
  • 22
  • 1
    Have you tried to look at the file manually in a shell while logged in as Oracle? It's not just the file permissions you need to check, the Oracle account has to be able to see the directory too. If it doesn't own the whole directory path that EXP_DATA points to then you'd have to chmod each directory to g+rx or o+rx depending on which group owns it and whether Oracle belongs to that group. I'm assuming the file (and the directory, of course) is on the DB server, not a client machine. – Alex Poole Feb 26 '16 at 16:12
  • Yes, I've logged in as `oracle` by `sudo su - oracle` and can see the file from shell. The owner of the parent directory also has been changed to `oracle` by `chown -R oracle ~/exp` . Now the permission is : `drwxrwxrwx 7 oracle srl 4096 Feb 27 09:18 exp ` . We're actually running as `localhost` (for test purpose), the file is in local hard drive. Is there any way to check the scenario inside code? Pls let's know if you need to know anything more. – Br. Sayan Feb 27 '16 at 04:06
  • Not sure what you mean about localhost and local hard drive - is the directory on the same machine the database itself is on? – Alex Poole Feb 27 '16 at 07:19
  • Yes, it is what I meant. I don't know precisely what made this, after doing the `chown` and `chmod`, we restarted the system and it started working. Thank you! It must have been permission issue, but couldn't find it earlier. Please post your comment as answer, so I can mark it as correct. – Br. Sayan Feb 27 '16 at 11:06

1 Answers1

0

It's an o/s file error...likely from permissions. The owner of the database shadow process that is executing the package is the o/s owner that needs permissions -- that's probably 'oracle'. You can test by logging in as 'oracle' on the database server and see if you can read the file in question. @alex poole offers a great thought to check the permissions of all parent directories.

Beege
  • 665
  • 4
  • 18