【问题标题】:How to execute unix command through odi and store the result in table如何通过odi执行unix命令并将结果存储在表中
【发布时间】:2013-11-22 15:37:15
【问题描述】:

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

提前致谢

【问题讨论】:

    标签: database oracle11g etl


    【解决方案1】:

    我不会使用 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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多