【问题标题】:Cannot insert explicit value for identity column with no primary key无法为没有主键的标识列插入显式值
【发布时间】:2014-04-27 14:44:30
【问题描述】:

我有一张桌子:

Ratings
---
PersonId int FKEY
FormId int FKEY
Rating int (NULLABLE)

当我执行这个查询时:

INSERT INTO Ratings (PersonId, FormId)
SELECT p.PersonId, f.FormId
FROM People p, Forms f

我得到这个错误:

当 IDENTITY_INSERT 设置为 OFF 时,无法为表“Ratings”中的标识列插入显式值。

有一次我不小心将两个外键列设置为复合主键,我担心可能存在某种形式的数据损坏。从长远来看,我可以做些什么来解决这个问题或修复我的问题?

【问题讨论】:

  • 如错误信息所示,如果要显式设置值,则需要将IDENTITY_INSERT 设置为ON
  • 我意识到,但我不应该这样做,没有主键,我已经对其他表进行了类似的查询。
  • 顺便说一句,我不确定你为什么要大量插入没有任何值的评级记录(甚至允许null评级) - 你可以简单地使用它们 没有这个表中有记录来记录这样的状态。
  • 该表命名不当,但必须维护人员与表单之间的关系,即使此人从未对该表单进行评分。大规模插入实际上只在一个小的现有用户网络中完成,这些用户可以访问所有表单。

标签: sql sql-server tsql


【解决方案1】:

请修改您的评级表结构。其中一个列(PersonId 或 FormId)被配置为 IDENTITY 列(一个序列),这没有任何意义,因为它们都是指向其他表的 FK。您应该从该表中的列(无论是 PersonId 还是 FormId)中删除 IDENTITY 属性。

【讨论】:

  • 我不小心用它们创建了一个复合键。我早就删除了它,但它的影响仍在继续。 SQL Server 没有检测到主键(或任何键,因为我擦除了所有内容),但限制仍在继续。我最终只是删除了表并使用相同的配置创建了一个新表(因为创建具有相同表名的相同模式并不能解决问题)。
  • @jokulmorder 列是否是标识列与它是否是任何键的一部分无关。因此,删除键不会将列更改为不再是标识列。
  • 我意识到,但我没有将身份规范设置为 true。我知道您确信这只是一个配置问题,但删除表并不允许我重新创建具有该名称的新表。这就是为什么我认为这是 SQL Management Studio 的问题。我的连接不是很好,所以我不太愿意排除服务器和客户端之间的数据损坏。
  • @jokulmorder (澄清一下,我不是发布此答案的人。)当然可以想象 SSMS 有一个错误,即删除表失败但由于某种原因不会导致正确要显示的错误信息。要排除此类问题,您可以避免表设计器(甚至完全避免 SSMS)并使用适当的 SQL 语句来删除和重新创建表。如果您愿意,可以使用 SSMS 为您生成脚本,然后在 SSMS 之外执行它。
  • 我为任何尖锐的语气道歉;这只是一个非常令人沮丧的问题。我将继续尝试脚本和查询。通过创建一个表并将其重命名为已删除的表,我确实取得了一些成功,但删除该表似乎并没有解决问题。
【解决方案2】:

这个脚本演示了IDENTITY_INSERT 是如何工作的。请检查 - 没有定义 PRIMARY KEY

CREATE TABLE dbo.Tool(ID INT IDENTITY, Name VARCHAR(40)) 
GO

SELECT * FROM dbo.Tool 
GO

SET IDENTITY_INSERT dbo.Tool ON 
GO

INSERT INTO dbo.Tool (ID, Name) VALUES (3, 'Garden shovel') 
GO

SELECT * FROM dbo.Tool 
GO

DROP TABLE dbo.Tool
GO

【讨论】:

  • 我 100% 确定该表没有主键。对于没有主键的表,IDENTITY_INSERT 属性是否默认设置为 true?
  • 不,没有这样的默认行为 - 您需要将 IDENTITY_INSERT 设置为 ON 明确
  • 所以看起来好像存在数据损坏问题。有没有办法通过 SQL Server 解决这个问题?
  • 我原来的帖子中的内容差不多就是这样:只是一个包含 2 个外键列的表,这些列在某一时刻偶然成为复合主键。我已经删除了该表,但我可以创建一个具有相同名称的新表,看看它是否仍然存在这些问题。第一次这样做并没有解决问题。
  • 我什至不能用这个表名创建一个新表,因为它认为旧表仍然存在(在管理工作室中不可见)。我将重新启动数据库服务器,看看是否能解决任何问题。
【解决方案3】:

尝试设置 IDENTITY_INSERT ON

SET IDENTITY_INSERT  [Table] ON
--Write your Insert  Query
SET IDENTITY_INSERT  [Table] OFF

【讨论】:

    猜你喜欢
    • 2015-10-27
    • 2016-04-13
    • 2015-07-02
    • 2019-05-28
    • 1970-01-01
    • 2017-03-05
    • 2018-12-12
    相关资源
    最近更新 更多