首页 > 解决方案 > 如何在 SQL Server 表中执行此插入

问题描述

我想将数据插入表tabA。我收到这个错误

违反 UNIQUE KEY 约束,无法在对象中插入重复键。

关键是(no_command, no_document, id_transc, project_cd)。

这是要插入的数据示例:

load_number | load_date | no_command | no_document | id_transc | div1 | div2 | activity_cd | project_cd
1             2021-04-10   38                          -1         0     200                  1
1             2021-04-10   38                          -1         600    0                   1

这不是相同的数据,因为 div1 和 div2 不同。我做了一个小组来解决问题,但它不起作用。我在 group by 中有这个错误。

列名无效

这是我的代码

INSERT INTO tabA ([load_number], [load_date], [no_command], [no_document],
                  [id_transc], [div1], [div2], [activity_cd], [project_cd])
    SELECT 
        1 [load_number], GETDATE() [load_date], id_cmd [no_command], '' [no_document],
        COALESCE(c.id_numb, -1) [id_transc],
        CASE
            WHEN b.data_type = 'primary' THEN b.amount
            ELSE 0
        END as [div1],
        CASE
            WHEN b.data_type = 'secondary' THEN b.amount
            ELSE 0
        END as [div2],
        COALESCE(d.budget_cd, -1) [activity_cd], code [project_cd]
    FROM
        tabB b
    LEFT JOIN 
        tabC c ON c.credit = b.account
    LEFT JOIN 
        tabD d ON d.activity = SUBSTRING([b.name], CHARINDEX('-', [b.name]) + 1, LEN([b.name])) 
               AND d.transc = '1010'
     GROUP BY
         [load_number], [load_date], [no_command], [no_document],
         [id_transc], [activity_cd], [project_cd]

我不是设计数据库的人,我无法对其进行更改。

需要帮助请...

标签: sqlsql-serversql-insert

解决方案


共享代码错误,因为数据违反了您尝试将其插入的表的主键。您有两条记录,虽然彼此不重复(它们具有不同的值Div1Div2正如您所说),但它们确实为所有主键字段共享相同的值。所以要么

  1. 该表需要更改以允许这两行,或者
  2. 这些行中的一个或两个应该被拒绝,或者
  3. 这两行应该以某种方式折叠成一行

我猜第三个选项是正确的,这样做的方法是使用和SUM返回的值。以下是我对您想要什么的最佳猜测:Div1Div2

SELECT
   1 [load_number],
   GETDATE() [load_date],
   id_cmd [no_command],
   '' [no_document],
   COALESCE(c.id_numb, -1) [id_transc],
   SUM(CASE WHEN b.data_type = 'primary' THEN b.amount ELSE 0 END) as [div1],
   SUM(CASE WHEN b.data_type = 'secondary' THEN b.amount ELSE 0 END) as [div2],
   COALESCE(d.budget_cd, -1) [activity_cd],
   code [project_cd]
FROM
   tabB b
   LEFT JOIN tabC c ON c.credit = b.account
   LEFT JOIN tabD d ON d.activity = SUBSTRING([b.name], CHARINDEX('-', [b.name]) + 1, LEN([b.name])) AND d.transc = '1010'
GROUP BY
   --Each of the things selected (which aren't static, getdate is static for these purposes) but aren't within aggregate functions appears below.
   --Note that they are not referenced by the alias given in the select clause.
   id_cmd,
   COALESCE(c.id_numb, -1),
   COALESCE(d.budget_cd, -1),
   code

在不知道您的数据的情况下很难判断,但即使这样做,您也可能会遇到问题。这是因为我们按不属于表主键的字段进行分组,即[activity_cd]字段(或COALESCE(d.budget_cd,-1))。如果两条记录可能在主键字段中一致,而在这条记录中不同,则此类数据将导致与您已经遇到的错误类似的错误。

正如 GordonLinoff 所提到的,确保您完全限定查询中引用的字段是一种很好的做法。你已经在一些地方(c.id_numb)而不是其他地方( )做到了这一点id_cmd。这有助于使代码更易于理解,并且可以防止代码在更改表模式导致字段名称变得模糊的情况下产生错误。


推荐阅读