【问题标题】:How to determine table row causing duplicate entry error in INSERT?如何确定在 INSERT 中导致重复输入错误的表行?
【发布时间】:2012-08-31 02:00:45
【问题描述】:

当我得到很多试图帮助我解决错误的答案时: 我最感兴趣的是一种进行错误处理和检测表行创建错误的方法,而不是解决我的实际问题,我只用它来说明存储过程中编码的内容。


我正在为表中缺少的条目在存储过程中执行 SQL 插入语句:

INSERT INTO dbo.t1
                      (col1, col2, col3, col4, col5)
    SELECT DISTINCT col1, col2, col3, col4, col5
    FROM         dbo.t2
    WHERE     (NOT EXISTS
                          (SELECT     col1, col2, col3, col4, col5
                            FROM      t1 AS Table_1
                            WHERE     (col1 = t2.col1) AND 
                                      (col2 = t2.col2) AND
                                      (col3 = t2.col3) AND
                                      (col4 = t2.col4) AND
                                      (col5 = t2.col5))) AND
                                       col2 = 'VALUE'

t1.col1 + t1.col2 和 t1.col3 + t1.col4 与另一个表 t3.col1 + t3.col2 有外键关系

存储过程未能完成抛出外键关系被破坏的错误信息;即 t3 中缺少一些条目:

消息 547,级别 16,状态 0 [...] INSERT 语句与 外键 [..]

我想知道的是导致错误的 t2 的 TABLE ROW,最好是该行中的值。我在 Google 上搜索了很多关于 SQL 错误处理的信息,但只找到了提供引发错误的编码行的示例——这对我来说是无用的信息......

任何帮助表示赞赏

【问题讨论】:

    标签: sql sql-server sql-server-2005 error-handling foreign-key-relationship


    【解决方案1】:

    这个错误很清楚,它看起来像是你试图在具有 FK 约束的列中插入一个值,而该值在引用表的主键列中找不到。

    从您发布的查询中,您尝试插入第一个表中不存在的 dbo.t2 中的所有值。然后,您可以使用 EXCEPT 运算符仅插入在 dbo.t2 中找到的 col1, col2, col3, col4, col5 的值,这些值在 dbo.t1 中不存在,例如:

    INSERT INTO dbo.t1
                      (col1, col2, col3, col4, col5)
    SELECT * FROM
    (
        SELECT col1, col2, col3, col4, col5
        FROM         dbo.t2
        EXCEPT 
        col1, col2, col3, col4, col5
        FROM         dbo.t1
    )
    

    这样,您将保证只插入不存在于dbo.t1 中的行。

    如果您想获取导致重复条目的数据,您可以使用INTERSECT 来获取它们。

    【讨论】:

    • 您好 Mahmoud,感谢您提出 EXCEPT 解决方案。不过,我不想知道如何停止查询以引发错误,但我想知道(T2 的)哪个表行正在创建错误。我想在存储的例程中捕获错误,然后创建一个输出告诉我它停止的行。
    • @WolfiG,啊哈,我认为这不可能。因为如果出现问题,插入将自动回滚。您可以编辑您的问题并详细说明,以便其他用户可以帮助您。
    【解决方案2】:
    SELECT column1, column2, column3
    FROM Table2 T2
    LEFT JOIN  Table1 T1 ON T1.col1 = T2.column1 and T1.col2 = T2.column2 and T1.col3=T2.column3
    WHERE T1.col1 IS NULL and T1.col2 IS NULL and T1.col3 IS NULL
    

    【讨论】:

      【解决方案3】:

      使用 NOT IN

      试试这个
        INSERT INTO TABLE_2  
       (id, name) SELECT t1.id,  t1.name   
        FROM TABLE_1 t1  WHERE t1.id NOT IN (SELECT id                        FROM TABLE_2) 
      

      【讨论】:

        【解决方案4】:

        您可以尝试对数据使用INNER JOIN来删除违规行。

        【讨论】:

        • 嗨,卡皮尔,和其他乐于助人的同事一样:对我来说,绕过错误并不是那么重要。我想知道在这种情况下如何找到导致错误的行。从interlectual的角度来看,我对此更感兴趣......
        【解决方案5】:

        我认为有可能,在t2 中,您的行的值在t3 中不存在。 (这就是违反引用的原因。)

        确保t2 仅包含t3 中存在的值。

        【讨论】:

        • 您好安德烈亚斯,感谢您的评论。不过,我不想知道如何停止查询以引发错误,但我想知道(T2 的)哪个表行正在创建错误。我想在存储的例程中捕获错误,然后创建一个输出告诉我它停止的行。这就是我想找出 t3 中缺少哪些条目的方式。
        • @WolfiG :我认为最好写一个这样的简单连接:SELECT * FROM t2 LEFT join T3 ON t2.col1 = t3.col1 AND t2.col2 = t3.col2 WHERE t3.col1 IS NULL Whit this 你可以找出那些记录。否则你在错误处理方面会遇到一些困难的问题,但使用 TRY-CATCH 也是可能的
        【解决方案6】:
        INSERT INTO dbo.t1(col1, col2, col3, col4, col5)
        SELECT DISTINCT col1, col2, col3, col4, col5
        FROM dbo.t2 left join dbo.t1
        on t2.col1=t1.col1 and
           t2.col2=t1.col2 and
           t2.col3=t1.col3 and
           t2.col4=t1.col4 and
           t2.col5=t1.col5 
        where t1.col1 is null and t1.col2 is null and t1.col3 is null and t1.col4 is null and t1.col5 is null
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-02-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多