我必须协调if数据是否从平面文件加载到表中。我必须创建一个oracle数据集成器包/接口/过程来执行unix命令来计算csv文件中的行数并将结果存储在一个表中然后我必须查询加载的表并在那里查询行数并存储在表和必须比较的是计数是否相同,请帮助我如何使包/接口/程序执行unix命令并将结果存储在oracle表中。
先谢谢
答案 0 :(得分:0)
我不会使用Oracle Data Integrator解决这个问题,而只是使用Oracle软件包。当已处理的文件位于同一节点上并且您可以使用utl_file和类似的包访问它时,可以这样做。您可以从PL / SQL打开CSV,计算可用的不同行结束样式的行(CR / LF / CRLF),然后再次关闭该文件。 这并没有提供运行UNIX语句的其他功能,例如'grep',但是使用utl_file,您可以打开/读取/写入/关闭文件,甚至可以通过一些努力列出目录中的文件。 一个免费的奖励是代码变得更容易移植到其他平台(Windows,VMS去了哪里?)。
请参阅下面的一些样本,这些样本取自我们在Invantive开发的软件(随意使用)。您可能希望使用load_xxx_from_directory,然后将regexp_count作为一个简单的解决方案。或者只是自己计算CR / LF / CRLF。
--
-- Load a file into a blob. Clob needed? Change blob to clob.
--
procedure load_blob_from_directory
( p_file out nocopy blob
, p_directory all_directories.directory_name%type
, p_filename varchar2
)
is
l_read_buffer_size constant pls_integer := 32767;
--
l_fh utl_file.file_type;
l_read_buffer raw(32767);
l_bytes_read_sofar integer;
l_bytes_read integer;
begin
if p_file is null
then
dbms_lob.createtemporary(p_file, true);
end if;
l_fh := utl_file.fopen(p_directory, p_filename, 'rb');
l_bytes_read_sofar := 0;
begin
while true
loop
utl_file.get_raw(l_fh, l_read_buffer, l_read_buffer_size);
l_bytes_read := length(l_read_buffer) / 2;
dbms_lob.write(p_file, l_bytes_read, l_bytes_read_sofar+1, l_read_buffer);
l_bytes_read_sofar := l_bytes_read_sofar + l_bytes_read;
end loop;
exception
when no_data_found
then
null;
end;
utl_file.fclose(l_fh);
exception
when others
then
--
-- Close file if necessary.
-- Ignore any errors.
--
begin
if utl_file.is_open(l_fh)
then
utl_file.fclose(l_fh);
end if;
exception
when others
then
null;
end;
--
rollback;
itgen_error_handler.add_to_inner_stack;
raise;
end;
保存到文件:
--
-- Save the file in blob format to an Oracle directory.
--
procedure save_blob_to_directory
( p_file blob
, p_directory all_directories.directory_name%type
, p_filename varchar2
)
is
l_piece_length constant pls_integer := 32767;
--
l_fh utl_file.file_type;
begin
l_fh := utl_file.fopen(p_directory, p_filename, 'wb');
for i in 0 .. trunc((dbms_lob.getlength( p_file ) - 1) / l_piece_length)
loop
utl_file.put_raw
( l_fh
, dbms_lob.substr
( p_file
, l_piece_length
, i * l_piece_length + 1
)
);
end loop;
utl_file.fclose(l_fh);
exception
when others
then
--
-- Close file if necessary.
-- Ignore any errors.
--
begin
if utl_file.is_open(l_fh)
then
utl_file.fclose(l_fh);
end if;
exception
when others
then
null;
end;
--
rollback;
itgen_error_handler.add_to_inner_stack;
raise;
end;
以下是获取文件大小的方法:
function get_file_length
( p_directory_name varchar2
, p_file_name varchar2
)
return number
is
l_file_length number;
l_file_exists boolean;
l_file_block_size number;
begin
utl_file.fgetattr
( location => p_directory_name
, filename => p_file_name
, fexists => l_file_exists
, file_length => l_file_length
, block_size => l_file_block_size
);
return l_file_length;
end;
以下是获取目录内容的方法:
function list_files
( p_directory_name all_directories.directory_name%type
)
return itgen_tab_file
pipelined
as
l_directory_path all_directories.directory_path%type;
l_ns varchar2(1024);
begin
select dry.directory_path
into l_directory_path
from all_directories dry
where dry.directory_name = p_directory_name
;
sys.dbms_backup_restore.searchfiles(l_directory_path, l_ns);
for r_files in
( select fname_krbmsft file_name
from sys.itgen_x_krbmsft
)
loop
pipe row
( itgen_rec_file
( p_directory_name
, r_files.file_name
, itgen_utilities.get_file_length (p_directory_name, r_files.file_name)
)
);
end loop;
end;