如何通过odi执行unix命令并将结果存储在表中

时间:2013-11-21 05:20:34

标签: database oracle11g etl

我必须协调if数据是否从平面文件加载到表中。我必须创建一个oracle数据集成器包/接口/过程来执行unix命令来计算csv文件中的行数并将结果存储在一个表中然后我必须查询加载的表并在那里查询行数并存储在表和必须比较的是计数是否相同,请帮助我如何使包/接口/程序执行unix命令并将结果存储在oracle表中。

先谢谢

1 个答案:

答案 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;