如何在 SQL 服务器 table 中插入

How to do this insert in a SQL Server table

我想将数据插入 table tabA。我收到此错误

Violation of UNIQUE KEY constraint, Cannot insert duplicate key in object.

关键是(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 来解决这个问题,但它不起作用。我在组中有这个错误。

Invalid column name

这是我的代码

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]

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

需要帮助...

您可以添加 where 子句 not exists:

where not exists (select 1
                  from tabA a
                  where a.no_command = ?.id_cmd and
                        a.no_document = '' and
                        a.id_transc = coalesce(c.id_numb,-1) and
                        a.project_cd = ?.code
                 )

? 用于 table 别名,用于定义列的来源。作为最佳实践,您应该限定所有查询中的所有列引用。这在使用相关子查询时尤为重要。

(写在这里会乱七八糟)。假设输出是正确的,你只是想聚合这些行:

WITH
  myData AS (
              SELECT
                       id_cmd                                                          [no_command]
                     , 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 id_cmd, COALESCE(c.id_numb, -1), COALESCE(d.budget_cd, -1), [code]
            )
INSERT INTO tabA([load_number], [load_date], [no_command], [no_document], [id_transc], [div1]
               , [div2], [activity_cd], [project_cd])
SELECT
     1, GETDATE(), [no_command], '', [id_transc], [div1], [div2], [activity_cd], [project_cd]
FROM myData;

请注意,当存在联接时,像 SUM() 这样的聚合可能会有问题。如果这些连接是一对多的,那么就可以了,否则要小心,在连接之前分别对 tabB 进行求和。

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

  1. table 需要更改以允许这两行,或者
  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

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

正如 GordonLinoff 所提到的,确保您完全限定查询中引用的字段是一种很好的做法。您已经在某些地方 (c.id_numb) 完成了此操作,但没有在其他地方 (id_cmd) 完成此操作。这有助于使代码更易于理解,并且可以防止代码在更改 table 架构导致字段名称变得不明确时产生错误。