如何在 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 的主键。您有两条记录,虽然它们彼此不重复(如您所说,它们对 Div1
和 Div2
具有不同的值),但它们确实为所有主键字段共享相同的值。所以要么
- table 需要更改以允许这两行,或者
- 应拒绝这些行中的一个或两个,或者
- 这两行应该以某种方式折叠成一行
我猜第三个选项是正确的,方法是 SUM
Div1
和 Div2
中返回的值。以下是我对您想要什么的最佳猜测:
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 架构导致字段名称变得不明确时产生错误。
我想将数据插入 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 的主键。您有两条记录,虽然它们彼此不重复(如您所说,它们对 Div1
和 Div2
具有不同的值),但它们确实为所有主键字段共享相同的值。所以要么
- table 需要更改以允许这两行,或者
- 应拒绝这些行中的一个或两个,或者
- 这两行应该以某种方式折叠成一行
我猜第三个选项是正确的,方法是 SUM
Div1
和 Div2
中返回的值。以下是我对您想要什么的最佳猜测:
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 架构导致字段名称变得不明确时产生错误。