Oracle 必须使用SQL加载器的控制文件避免所有记录出现多次

Oracle 必须使用SQL加载器的控制文件避免所有记录出现多次,oracle,sql-loader,controlfile,Oracle,Sql Loader,Controlfile,我希望避免使用SQL Loader将所有记录插入表中。我们要插入的表的主键超过3列。每当发生重复时,代码就会失败,主键冲突 在使用控制文件插入时,我需要跳过/避免数据文件中出现多次的所有记录。有人能帮我吗 有没有办法通过在控制文件本身中添加一些条件来跳过这些记录?对我来说,您似乎在寻找一个问题,而根本没有问题 有一张桌子 它有一个主键约束集 有一个包含数据的文件,其中一些是重复的(根据主键列的含义) 加载会话开始 满足所有条件的行将成功加载到表中 不加载违反任何内容(包括主键约束)的行 它(

我希望避免使用SQL Loader将所有记录插入表中。我们要插入的表的主键超过3列。每当发生重复时,代码就会失败,主键冲突

在使用控制文件插入时,我需要跳过/避免数据文件中出现多次的所有记录。有人能帮我吗


有没有办法通过在控制文件本身中添加一些条件来跳过这些记录?

对我来说,您似乎在寻找一个问题,而根本没有问题

  • 有一张桌子
  • 它有一个主键约束集
  • 有一个包含数据的文件,其中一些是重复的(根据主键列的含义)
  • 加载会话开始
  • 满足所有条件的行将成功加载到表中
  • 不加载违反任何内容(包括主键约束)的行
    • 它(错误)记录在
      .log
      文件中
    • 这些行现在位于
      .bad
      文件中
  • 加载完成后,表中只包含不同的行
以防您不知道,这里有
errors
参数;其值为整数,它显示您希望允许的错误数:

  • 默认值为50
  • 如果不想允许任何错误,请将其设置为0
  • 如果要允许任意数量的错误,请将其设置为非常高的值
那么,问题是什么?我没有看到


看起来,在重复的情况下,您不想加载这些行中的任何一行,因为您不知道哪一行是正确的,我认为SQL Loader无法做到这一点

一个选项是切换到外部表,该表以输入文件为源,充当“普通”表,允许您直接编写
SELECT
语句,而无需事先将数据加载到数据库中。它允许您跳过重复项,例如

insert into target_table (col1, col2, ...)
  select col1, col2, ...
  from external_table a
  where (a.pkcol1, a.pkcol2, pkcol3) not in 
        (select b.pkcol1, b.pkcol2, b.pkcol3
         from external_table b
         group by b.pkcol1, b.pkcol2, b.pkcol3
         having count(*) > 1
        );
delete from target_table a
      where (a.pkcol1, a.pkcol2, pkcol3) in 
            (select b.pkcol1, b.pkcol2, b.pkcol3
             from target_table b
             group by b.pkcol1, b.pkcol2, b.pkcol3
             having count(*) > 1
            );
或者,您可以禁用主键约束,按现在的方式加载数据(包括重复项),然后删除所有重复项,例如

insert into target_table (col1, col2, ...)
  select col1, col2, ...
  from external_table a
  where (a.pkcol1, a.pkcol2, pkcol3) not in 
        (select b.pkcol1, b.pkcol2, b.pkcol3
         from external_table b
         group by b.pkcol1, b.pkcol2, b.pkcol3
         having count(*) > 1
        );
delete from target_table a
      where (a.pkcol1, a.pkcol2, pkcol3) in 
            (select b.pkcol1, b.pkcol2, b.pkcol3
             from target_table b
             group by b.pkcol1, b.pkcol2, b.pkcol3
             having count(*) > 1
            );

然后重新启用主键约束。

对“问题”的一种解释可能是“数据文件中有3条记录具有相同的主键信息,并且不应加载这三条记录”。在您的场景中,我认为第一个将被加载(没有冲突记录),但第二个和第三个将被拒绝。而且,根据我的假设,这不是用户想要的。也许吧,@Jonathan。不过,这对我来说没什么意义。好吧,你不想要复制品,没关系。但为什么不加载不违反约束的行呢?怎么了?如果你不知道三条语句中的哪一条是真的,那么最好将这三条语句都保留在数据库之外,而不是插入一条结果为假的语句。这不是常见的情况;这是一个似是而非的情景(当然,在国际海事组织)。但你完全正确,在这个阶段,等待OP澄清是唯一明智的选择。不过我没有屏住呼吸。是的,你说得对。数据文件中有三条语句具有相同的主键信息,我们不确定哪一条是正确的。因此,我希望避免/跳过所有这三条记录来加载。请建议我在答案中添加更多信息;请看一看。我们应该如何解释您的要求?假设数据文件中有3条记录具有相同的主键信息,与任何现有记录都不冲突。您是否要求这三个都不加载?或者第一个将被加载(没有冲突记录),但是第二个和第三个将被拒绝,这是可以接受的吗?如果是前者(不应该加载任何记录),我不确定是否有办法将指令发送给SQL Loader。但是,您可以对文件进行预处理以删除此类重复记录。不太容易,但也不太难。如果先将文件加载到临时表中,然后在过滤掉所有不需要的记录后将其加载到最终表中,该怎么办?如果要重新建模,则可以从select语句中插入,例如
select a.c1、a.c2、a.c3、b.c4 from temp_table a LEFT JOIN temp_table b ON(a.c1=b.c1和a.c2=b.c2和a.c3=b.c3)按a.c1、a.c2、a.c3、b.c4分组,其计数(a.c1)=1