SQL 更新:无法更改第一条记录的复合键值之一

Posted

技术标签:

【中文标题】SQL 更新:无法更改第一条记录的复合键值之一【英文标题】:SQL Update: Cannot change one of composite key value of first record 【发布时间】:2011-05-01 12:17:41 【问题描述】:

MSSQL Server 中,我有一个 StudentCourse 表,其中包含 复合主键StudentID课程ID)。我正在尝试将所选学生更改为另一门课程。 每个课程组的一个学生记录阻止我进行UPDATE 操作。

StudentID CourseID

   1          1
   1          2
   1          3
   2          2
   2          3
   2          4

我可以将 (1, 2)(1, 3) 记录的 CourseID 更新为 5 ,但我无法将 (1, 1) 记录的 CourseID 更新为 5。同样,我可以将 (2, 2)(2, 3) 记录的 CourseID 更新为 5,但我无法将 (2,4) 记录的 CourseID 更新为 5

此类 CourseID 组中只有一条记录阻止我更改其 CourseID 字段。我收到以下错误。

违反 PRIMARY KEY 约束 'PK_StudentCourse'。无法插入 对象中的重复键 '学生课程'。该声明有 被终止了。

我不知道是每组的第一条还是最后一条记录禁止我更改CourseID。我确定在 StudentCourse 表中没有 CourseID = 5 的记录,并且我有一个 CourseID5 在课程表中。

任何帮助将不胜感激。

【问题讨论】:

出现错误的更新语句是什么样的? 您可以尝试运行SELECT CourseID From StudentCourse WHERE CourseID = 5 并验证确实没有此类记录吗? 您能否更新问题以包含如何为您的索引编写脚本?另外,我假设您不想在此表中允许重复(这意味着没有学生应该能够两次注册同一课程)。对吗? @Mikal,两个失败的 UPDATE 语句是“UPDATE StudentCourse SET CourseID = 5 WHERE CourseID = 1 AND St​​udentID IN(1)”和“UPDATE StudentCourse SET CourseID = 5 WHERE CourseID = 2 AND St​​udentID IN( 4)”所有其他 UPDATE 语句都有效,例如“UPDATE StudentCourse SET CourseID = 5 WHERE CourseID = 1 AND St​​udentID IN(2,3)”、“UPDATE StudentCourse SET CourseID = 5 WHERE CourseID = 2 AND St​​udentID IN(2,3) " @Menahem,SELECT CourseID=5 返回零行。 @rsbarror。 @rsbarro,这是正确的。表中不应有两个相同的 StudentID 和两个相同的 CourseIDs 记录。 【参考方案1】:

您看到的错误意味着您正在尝试创建与另一个现有记录具有相同主键值的记录。你在这里犯了一个错误,但你没有提供足够的信息来理解你的错误是什么。

当我遇到问题时,我发现创建一个可以说明问题的小型 repro 很有用,以便我可以将其展示给其他用户。有时,当我尝试创建一个简单的复制品时,复制品实际上可以正常工作。这让我知道这个工作“repro”和我的问题案例有一些不同。对我来说,下一步是弥合它们之间的差距,修改它们中的任何一个以使它们更接近,直到行为差异消失。成功的步骤通常会揭示正在调查的行为的罪魁祸首。

在您的情况下,我可以执行以下简单步骤来证明 SQL Server 正在按预期运行:

我创建一个表:

CREATE TABLE [dbo].[StudentCourse](
    [StudentID] [int] NOT NULL,
    [CourseID] [int] NOT NULL,
 CONSTRAINT [PK_StudentCourse] PRIMARY KEY CLUSTERED 
(
    [StudentID] ASC,
    [CourseID] ASC
))

我在以下位置添加测试数据:

INSERT INTO [dbo].[StudentCourse] values (1,1)
INSERT INTO [dbo].[StudentCourse] values (1,2)
INSERT INTO [dbo].[StudentCourse] values (1,3)
INSERT INTO [dbo].[StudentCourse] values (2,2)
INSERT INTO [dbo].[StudentCourse] values (2,3)
INSERT INTO [dbo].[StudentCourse] values (2,4)

我执行您描述的更新:

UPDATE [dbo].[StudentCourse] SET CourseID = 5 where StudentId = 2 and CourseID = 4
UPDATE [dbo].[StudentCourse] SET CourseID = 5 where StudentId = 1 and CourseID = 1

我可以看到这些工作正常。

试着了解你在做什么不同,你会找到问题的原因。

【讨论】:

我在另一个数据库中也尝试过,它也有效,但我不能只是删除表并重新创建。我可以备份数据,但它会破坏一切、关系、索引等。我认为该表中的某些规则可能存在问题。【参考方案2】:

我发现了问题。当我为查询字符串构建条件时,一个条件没有添加 GroupID 条件。当该记录包含在查询字符串中时,查询字符串恰好错过了该 GroupID crieria。它发生如下。

UPDATE StudentCourse SET CourseID = 5 WHERE CourseID = 1 AND StudentID IN(2,3)
UPDATE StudentCourse SET CourseID = 5 WHERE StudentID IN(1,2,3)

UPDATE StudentCourse SET CourseID = 6 WHERE CourseID = 2 AND StudentID IN(2,3)
UPDATE StudentCourse SET CourseID = 6 WHERE StudentID IN(2,3,4)

当然,我的查询违反了没有 CourseID 条件的主键规则。谢谢你的时间,伙计们。

【讨论】:

以上是关于SQL 更新:无法更改第一条记录的复合键值之一的主要内容,如果未能解决你的问题,请参考以下文章

eclipse-android开发过程中,将sqlite字段原值手工修改后,无法查询到关联的下一个表

VB.NET 无法更新 datagridview 中的 SQL 数据

在 CICS 中浏览 KSDS 时无法读取下一条记录

Sql Server 查找下一个最近更改的记录

插入一条记录时“无法修改列[列名= id]”

[MySQL] SQL_ERROR 1032解决办法