2011-10-21 41 views
0

我有一个由三列组成的主键:CODE_TARIF, UNITE, MODE_LIV。在我的表格中有三个记录MODE_LIV = 2。然后我插入一个记录MODE_LIV = 4SQL INSERT违例主键

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

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

+3

您正在为所有PK列插入具有相同值的3行。 (实际上所有的非PK列) –

回答

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_TARIF,UNITEMODE_LIV的组成是三个重复记录。

1

如果我正确地读你的文章,你有复合PK由(CODE_TARIF,团结和MODE_LIV)

在这种情况下,您的插入尝试与PK

'Livr_A_50_99','1', '4' 
插入所有3行

如果您不打算插入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)的行区分
- 只插入重复的行
之一 - 修改您的数据,这样只需要插入一次(如添加'count'字段)
- 修改您的数据,以便PK字段与任何其他行不相同