如何查找违反唯一键约束的记录?

时间:2016-01-27 17:33:14

标签: sql oracle

假设我有两个表,如下所示,

表A

    +-------+-------+-------+-------+
    | col_a | col_b | col_c | col_d |
    +-------+-------+-------+-------+
    |       |       |       |       |
    +-------+-------+-------+-------+

表B

    +-------+-------+-------+-------+
    | col_a | col_b | col_c | col_d |
    +-------+-------+-------+-------+
    |       |       |       |       |
    +-------+-------+-------+-------+

我将使用表B更新表A.以下是条件

  1. col_a等于的记录应在表A中更新
  2. 记录不等于col_a应插入表A
  3. 表A具有唯一键约束(col_b,col_c,col_d)
  4. 问题是在更新表A中的数据时,某些记录的此唯一键约束失败。 问题是如何使用查询识别违反唯一键约束的记录。 (我无权访问日志)

4 个答案:

答案 0 :(得分:9)

如果您在col_b, col_c, col_d table_b上没有唯一密钥,则复制时会导致违规。您可以使用如下查询识别有问题的行:

SELECT col_b, col_c, col_d
  FROM table_b
  GROUP BY col_b, col_c, col_d
  HAVING COUNT(*) > 1

可以在加入table_a的{​​{1}}上运行类似的查询,但要运行的具体查询将取决于table_b中要更新的列。对于插入案例,一种有用的技术可能是在table_a和建议的插入行之间使用MINUS

答案 1 :(得分:2)

如果我正确理解了您的需求,也许这样的事情可以找到会产生问题的行:

select *
from table_a a
inner join table_b b 
on (a.col_b  = b.col_b and
    a.col_c  = b.col_c and
    a.col_d  = b.col_d and
    a.col_a != b.col_a
   )

答案 2 :(得分:0)

USE合并声明 在Cols b,c,d上匹配时更新 和不匹配时插入。

单个合并声明将解决您的问题Ex。

            MERGE INTO A a
            USING B b
            ON (a.colb = b.colb and a.colc=b.colc and so on..)
            WHEN MATCHED THEN
            UPDATE SET a.cola= b.cola
            WHEN NOT MATCHED THEN
            INSERT (collist)
            VALUES (b.cols);

答案 3 :(得分:0)

我刚刚通过以下步骤确定了唯一约束的违规者(我认为这非常简单):

  1. 删除表A上的约束/唯一索引
  2. 运行查询以更新/插入/合并到表A
  3. 运行

    select col_b, col_c, col_d, count(*)
    from Table A
    group by col_b, col_c, col_d
    having count(*) > 1
    
  4. 查询结果显示您的罪魁祸首
  5. 修复数据/查询
  6. 在表A上重新创建约束/唯一索引
  7. 重新运行查询,它应该可以工作(手指交叉)