哪些代码在db中有对应关系

时间:2012-07-30 11:49:37

标签: sql database oracle csv plsql

我面临着必须查看具有数百万条记录的数据库的任务,一组约1500条记录的代码具有相应的记录,其中一些记录存在于数据库中。例如,我在csv文件中有1500个ID。我想知道数据库中存在哪些ID,因此是正确的,哪些不存在。

如果没有“...... WHERE id IN (1, 2, 3, ..., 1500);”,有没有更好的方法呢? 有问题的DB /语言是ORACLE PL / SQL。

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

在CSV文件上构建外部表。这些是非常巧妙的东西,它们允许我们在SQL中查询OS文件的内容。 Find out more

然后发出查询很简单:

select csv.id
       , case ( when tgt.id is null then 'invalid' else 'valid') end as valid_id
from your_external_tab csv
       left join target_table tgt on (csv.id = tgt.id)

  

“从性能的角度来看,CSV表并不理想”

表现是一个背景问题。在这种情况下,它取决于CSV中的数据更改的频率以及我们查询它的频率。如果文件每天生成一次,我们只需要在交付后检查它们,那么外部表是最有效的解决方案。但是,如果这个数据集是一个需要经常查询的永久存储库,那么写入堆表的开销显然是合理的。

对我而言,一个由一堆ID组成的CSV文件听起来就像瞬态数据一样 适合外部表的用例。但是OP可能有其他要求,他们没有提到。


这是一种替代方法,不需要创建任何永久数据库对象。因此它不那么优雅,而且可能表现更差。

它使用UTL_FILE实时读取CSV文件,并根据SYSTEM.NUMBER_TBL_TYPE填充一个集合,SYSTEM.NUMBER_TBL_TYPE是一个预定义的集合(NUMBER的嵌套表),应该在Oracle数据库中可用。

declare
    ids system.number_tbl_type;
    fh utl_file.file_handle;
    idx pls_integer := 0;
    n pls_integer;
 begin
    fh := utl_file.fopen('your_data_directory', 'your_data.csv', 'r');
    begin
        utl_file.get_line(fh, n);
        loop  
            idx := idx + 1;
            ids.extend();
            ids(idx) := n;
            utl_file.get_line(fh, n);
        end loop;
   exception
      when no_data_found then
          if utl_file.is_open(fh) then
             utl_file.fclose(fh);
          end if;
     when others then
          raise;
  end;
  for id_recs in  in  ( select csv.column_value 
              , case ( when tgt.id is null then 'invalid' else 'valid') end as valid_id
                from (select * from table(ids)) csv
            left join target_table tgt on (csv.column_value = tgt.id)
  ) loop
  dbms_output.put_line '(ID '||id_recs.column_value || ' is '||id_recs.valid_id);
  end loop;
end;

注意:我没有测试过这段代码。原则是合理的,但细节可能需要调试;)