SQL INSERT违反主键

时间:2011-10-21 13:29:51

标签: sql primary-key

我有一个主键由三列组成的表: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

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

5 个答案:

答案 0 :(得分: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 :(得分:1)

观察你的查询我看到你试图在具有主键的表中插入的三个完全相同的记录(由于构建PK的三个字段是相同的'Livr_A_50_99', '1', '4'而被违反了)!!

答案 2 :(得分:1)

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

答案 3 :(得分: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

答案 4 :(得分:1)

主键用于标识单行数据。

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

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