【问题标题】:Violation of Primary Key Constraint on Composite Key违反组合键的主键约束
【发布时间】:2012-04-24 20:45:23
【问题描述】:
INSERT INTO tbl_AllParcel
           ([P_ID],[Sub_ID],[X_COORD],[Y_COORD])

VALUES 
       ('0706' , '002' , '579002' , '1167176'),
       ('0706' , '003' , '579013' , '1167153')

P_ID 和 Sub_ID 都是主键,它们共同构成一个复合键。我收到以下错误消息,我运行上面的代码。唯一值不应该由复合键单独创建吗?

消息 2627,第 14 级,状态 1,第 2 行 违反主键约束“PK_tbl_Parcel”。无法在对象“dbo.tbl_AllParcel”中插入重复键。 声明已终止。

【问题讨论】:

    标签: sql-server


    【解决方案1】:

    尝试分别插入两行。我敢打赌至少有一个失败,但不一定两者都失败。失败不是来自仅在插入语句中找到的数据,除非您在各个列上同时具有复合主键/唯一约束和另一个唯一约束。

    您还可以解释一下您是如何将两个主键一起形成一个复合键的吗?一张表只能有一个主键。您能否编写表定义脚本(在 SSMS 中的对象资源管理器中单击鼠标右键,将表编写为,创建到,剪贴板),并将其添加到问题中,以便我们就术语达成一致?

    如果你对 P_ID 有唯一约束,对 Sub_ID 有唯一约束,那么你只能在表中拥有 each 值之一,这与我认为你想要的相反(只有组合必须是唯一的)。如果您对各个列有唯一约束,则这是无效的,因为它不违反组合约束,但确实违反了第一列的约束:

    P_ID Sub_ID
    ---- ------
    0706 002
    0706 003
    

    我们可以告诉您如何解决此问题(并确认没有 P_ID = '0706' 且 Sub_ID = '002' 或 '003' 的行)。当你这样说时会发生什么:

    SELECT COUNT(*) FROM dbo.tbl_AllParcel WHERE P_ID = '0706' AND Sub_ID = '002';
    

    ?或者更重要的是,我想,这取决于您提供的脚本:

    SELECT COUNT(*) FROM dbo.tbl_AllParcel WHERE P_ID   = '0706';
    SELECT COUNT(*) FROM dbo.tbl_AllParcel WHERE Sub_ID = '002';
    

    要在不向单个列添加键的情况下创建复合键,请不要选择单个列。这是使用CREATE TABLE 的一种方法:

    CREATE TABLE dbo.tbl_AllParcel2
    (
      P_Id   CHAR(4),
      Sub_Id CHAR(3),
      ... other columns,
      CONSTRAINT PK_Parcel PRIMARY KEY(P_Id, Sub_Id)
    );
    

    我假设您当前正在使用 UI。不要尝试在表格设计器中执行此操作 - 这是一大堆垃圾。学习 DDL,它会让你走得更远。以下是联机丛书中的CREATE TABLEALTER TABLE 主题,其中有大量用于定义各种约束和其他表属性的示例:

    CREATE TABLE (MSDN)
    ALTER TABLE (MSDN)

    【讨论】:

    • 谢谢亚伦!下面是代码 CREATE TABLE [dbo].[tbl_AllParcel]( [P_ID] [nvarchar](10) NOT NULL, [Sub_ID] [nvarchar](10) NOT NULL, [X_COORD] [int] NULL, [Y_COORD] [ int] NULL,CONSTRAINT [PK_tbl_Parcel] 主键集群([P_ID] ASC,[Sub_ID] ASC
    • ALTER TABLE [dbo].[tbl_AllParcel] WITH CHECK ADD CONSTRAINT [FK_tbl_AllParcel_tbl_AllParcel] FOREIGN KEY([P_ID], [Sub_ID]) REFERENCES [dbo].[tbl_AllParcel] ([P_ID], [Sub_ID] ]) GO ALTER TABLE [dbo].[tbl_AllParcel] 检查约束 [FK_tbl_AllParcel_tbl_AllParcel] GO
    • 查询结果为一条记录。你所说的当然是正确的,尤其是第 3 段中关于我的意图的评论。我只是不知道在不对单个键施加主键约束的情况下创建复合键的任何其他方法。请告诉我我错了!
    • 根据您在评论中提交的代码(对不起,我在编辑帖子之前没有看到),您似乎已经有一个复合PK。但是,该脚本可能不包括对单个列的唯一索引或唯一约束。您尝试在问题中插入的数据不起作用,因为其中一行已经存在。如果要插入所有有效行,请将它们分成单独的插入,而不是使用组合的 VALUES() 子句。
    • 感谢大家的意见。我别无选择,只能重构数据库中的关键约束。
    【解决方案2】:

    此错误意味着您已经在该组合键的表中获得了这两个之一。

    '0706' , '002' 
    '0706' , '003' 
    

    【讨论】:

    • SQL server 2008 能否创建不具有唯一单个键的复合键?我想在上面的数据中实现什么
    猜你喜欢
    • 2022-01-06
    • 2012-07-15
    • 2021-04-11
    • 2016-08-24
    • 1970-01-01
    • 2023-03-30
    • 2021-04-14
    • 2014-08-12
    • 1970-01-01
    相关资源
    最近更新 更多