假设我有一个空的ProductLocalizations
表,其中复合主键由ProductId
和LanguageCode
字段组成,我执行以下查询。
INSERT INTO dbo.ProductLocalizations (ProductId, LanguageCode, Name, Description)
SELECT ProductId, LanguageCode1, Name1, Description1 FROM dbo.BulkProducts
WHERE ProductId NOT IN (SELECT ProductId FROM dbo.ProductLocalizations) UNION
SELECT ProductId, LanguageCode2, Name2, Description2 FROM dbo.BulkProducts
WHERE ProductId NOT IN (SELECT ProductId FROM dbo.ProductLocalizations) UNION
SELECT ProductId, LanguageCode3, Name3, Description3 FROM dbo.BulkProducts
WHERE ProductId NOT IN (SELECT ProductId FROM dbo.ProductLocalizations) UNION
SELECT ProductId, LanguageCode4, Name4, Description4 FROM dbo.BulkProducts
WHERE ProductId NOT IN (SELECT ProductId FROM dbo.ProductLocalizations)
从我的(有限的)SQL知识,因为查询包含
WHERE ProductId NOT IN (SELECT ProductId FROM dbo.ProductLocalizations)
子句,不应该以任何方式插入重复(无效)记录。但是,执行此操作时,我会收到
Msg 2627,Level 14,State 1,Line 1违反PRIMARY KEY 约束' PK_dbo.ProductLocalizations'。无法插入重复键 在对象&#d ;.ProductLocalizations'。重复的键值是 (29977,de)。声明已经终止。
我错过了什么?
答案 0 :(得分:5)
您的表格中有一个由String
和ProductId
组成的复合主键。您需要修改LanguageCode
子句以使用WHERE
。此外,seeing as you're unpivoting the table, you may want to use CROSS APPLY
to improve the speed:
NOT EXISTS
如果您无法使用INSERT INTO dbo.ProductLocalizations (ProductId, LanguageCode, Name, Description)
SELECT
bp.ProductId, t.LanguageCode, t.Name, t.Description
FROM dbo.BulkProducts bp
CROSS APPLY(
VALUES (LanguageCode1, Name1, Description1),
(LanguageCode2, Name2, Description2),
(LanguageCode3, Name3, Description3),
(LanguageCode4, Name4, Description4)
) t(LanguageCode, Name, Description)
WHERE NOT EXISTS(
SELECT 1
FROM dbo.ProductLocalizations p
WHERE
p.ProductId = bp.ProductId
AND p.LanguageCode = t.LanguageCode
)
,则此处是改进的CROSS APPLY
版本:
UNION ALL
答案 1 :(得分:0)
SELECT ProductId, LanguageCode1, Name1, Description1 FROM dbo.BulkProducts
WHERE ProductId NOT IN (SELECT ProductId FROM dbo.ProductLocalizations) UNION
SELECT ProductId, LanguageCode2, Name2, Description2 FROM dbo.BulkProdu
WHERE ProductId NOT IN (SELECT ProductId FROM dbo.ProductLocalizations) UNION
SELECT ProductId, LanguageCode3, Name3, Description3 FROM dbo.BulkProdu
WHERE ProductId NOT IN (SELECT ProductId FROM dbo.ProductLocalizations) UNION
SELECT ProductId, LanguageCode4, Name4, Description4 FROM dbo.BulkProdu
WHERE ProductId NOT IN (SELECT ProductId FROM dbo.ProductLocalizations)
您的选择查询返回productID和languagecode列的重复值