SQL INSERT违反主键

问题描述 投票:0回答:5

我有一个表,主键由三列组成:CODE_TARIF, UNITE, MODE_LIV。在我的表中有三个记录与MODE_LIV = 2。然后我用MODE_LIV = 4插入一条记录。

INSERT INTO T_TARIF (
    CODE_TARIF, ZONE, UNITE, MODE_LIV, LIBELLE, TR_DEBUT, TR_FIN, MONTANT
) 
SELECT 'Livr_A_50_99', '2', '1', '4', 'sdg', '50', '99', '90' 
UNION ALL 
SELECT 'Livr_A_50_99', '2', '1', '4', 'sdg', '50', '99', '90' 
UNION ALL 
SELECT 'Livr_A_50_99', '2', '1', '4', 'sdg', '50', '99', '90'

它返回一个错误(违反主键),这没有任何意义,因为MODE_LIV = 2不等于MODE_LIV = 4

我知道我可以添加一个代理键作为自动递增的标识列,但在我的情况下,这不是一个选项。

sql primary-key
5个回答
4
投票

您正在主键字段中插入3行具有相同数据的行。 当然你会遭到PK违规。

将代码更改为:

INSERT INTO T_TARIF (CODE_TARIF, ZONE, UNITE, MODE_LIV, LIBELLE, TR_DEBUT, TR_FIN, MONTANT) 
SELECT 'Livr_A_50_99', '2', '1', '3', 'sdg', '50', '99', '90' 
UNION ALL 
SELECT 'Livr_A_50_99', '2', '1', '4', 'sdg', '50', '99', '90' 
UNION ALL 
SELECT 'Livr_A_50_99', '2', '1', '5', 'sdg', '50', '99', '90'

//Different data for every row    ^

1
投票

看着你的查询我看到三个完全相同的记录,你试图在一个有主键的表中插入(这是违反的,因为构建PK的三个字段是相同的'Livr_A_50_99', '1', '4')!


1
投票

我猜“三个主键”你的意思是复合键。在您的情况下,您的主键不能有重复数据,CODE_TARIFUNITEMODE_LIV的组成是三个重复记录。


1
投票

如果我正确阅读了你的帖子,你有一个由(CODE_TARIF,UNITE和MODE_LIV)组成的复合PK

在这种情况下,您的插入尝试使用PK插入所有3行

'Livr_A_50_99','1', '4'

如果你不打算插入完全相同的数据3次,那么用UNION ALL替换你的UNION,这只会插入一次行。

如果您打算使用代理自动递增PK,则需要将表DDL更改为

CREATE TABLE T_TARIF
(
    T_TARIF_Id INT identity(1,1) NOT NULL,
... Other fields here

)
GO

ALTER TABLE T_TARIF ADD CONSTRAINT PK_Tariff PRIMARY KEY(T_TARIF_Id)
GO

1
投票

主键用于标识单行数据。

在您的示例中,您将插入3个相同的数据行。这意味着主键将识别所有三行,而不仅仅是一行。根据定义,这是主键违规。

你的选择是: - 添加新字段(例如自动增量id)以区分行 - 只插入一个重复的行 - 修改您的数据,使其只需插入一次(例如添加'计数'字段) - 修改数据,使PK字段与任何其他行不同

© www.soinside.com 2019 - 2024. All rights reserved.