【发布时间】:2016-06-09 22:40:12
【问题描述】:
我们在 Ubuntu 上的 SQL 过程中遇到以下错误。相同的过程在 Windows 上正确执行。该过程的目标是将.csv 文件导入到外部oracle 表中。
Oracle 错误:
ORA-29283: invalid file operation ORA-06512: at "SYS.UTL_FILE", line 536 ORA-29283: invalid file operation
这个 SO question 可能是一个解决方案,但即使在给相关文件适当的权限 chmod 777(在这种情况下解决了问题)之后,我们也面临同样的错误。
ORA-29283: invalid file operation ORA-06512: at "SYS.UTL_FILE", line 536
程序的相关部分是:
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;
发生错误的行是:
file_handle := UTL_FILE.FOPEN('EXP_DATA',i.file_name,'R');
赋予文件的权限如下:
-rwxrwxrwx 1 rama rama 240 Feb 26 11:24 exp_41_02_2016.csv`
如何追踪导致此问题的问题? 如果您需要任何其他信息,请告诉我?
【问题讨论】:
-
您是否尝试在以 Oracle 身份登录时在 shell 中手动查看文件?您需要检查的不仅仅是文件权限,Oracle 帐户也必须能够查看目录。如果它不拥有 EXP_DATA 指向的整个目录路径,那么您必须根据哪个组拥有它以及 Oracle 是否属于该组,将每个目录 chmod 为 g+rx 或 o+rx。我假设文件(当然还有目录)在数据库服务器上,而不是客户端机器上。
-
是的,我已经通过
sudo su - oracle以oracle登录,并且可以从shell 中看到该文件。父目录的所有者也已由chown -R oracle ~/exp更改为oracle。现在权限是:drwxrwxrwx 7 oracle srl 4096 Feb 27 09:18 exp。我们实际上以localhost运行(用于测试目的),该文件位于本地硬盘驱动器中。有没有办法检查代码中的场景?如果您需要了解更多信息,请告诉我们。 -
不确定本地主机和本地硬盘驱动器是什么意思 - 数据库本身所在的同一台计算机上的目录?
-
是的,这就是我的意思。我不知道是什么原因造成的,在执行
chown和chmod之后,我们重新启动系统并开始工作。谢谢!一定是权限问题,但之前找不到。请发表您的评论作为答案,以便我将其标记为正确。
标签: sql oracle stored-procedures oracle11g