【问题标题】:Why do I get sql error "Violation of PRIMARY KEY constraint"为什么我会收到 sql 错误“违反 PRIMARY KEY 约束”
【发布时间】:2015-06-05 18:10:33
【问题描述】:

我有一张桌子

CREATE TABLE [dbo].[DocGenVariable](
[userkey_sessionid] [varchar](38) NOT NULL,
[is_session] [bit] NULL,
[var_name] [nvarchar](255) NOT NULL,
[var_value] [nvarchar](1000) NOT NULL,
[topic_id] [varchar](38) NOT NULL,
[resource_id] [int] NULL,
[added] [datetime] NOT NULL,

CONSTRAINT [PK_DocGenVariable] PRIMARY KEY CLUSTERED 
(
    [userkey_sessionid] ASC,
    [var_name] ASC,
    [topic_id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

有时(注意>有时)我会收到错误

"Violation of PRIMARY KEY constraint 'PK_DocGenVariable'. 
Cannot insert duplicate key in object 'dbo.DocGenVariable'.

当我尝试在此表中添加条目时

delete from DocGenVariable where userkey_sessionid = @key_session and var_name = @var_name and topic_id = @topic_id 

if (LTRIM(RTRIM(@var_value)) <> '')
    begin
        insert into DocGenVariable(userkey_sessionid, is_session, var_name, var_value, topic_id, resource_id, added)
        values (@key_session, @is_session, @var_name, @var_value, @topic_id, @resource_id, GetDate())
    end

我首先要做的是删除一个必须更新的条目,然后添加一个新条目。

为什么会出现这个约束错误?

【问题讨论】:

  • 您的插入语句没有插入到您提供格式的表中。不要发布图片,而是编写 create table 语句并发布。
  • 您提供了 DocGenAdvVariable 的表 def 和 DocGenVariable 的语句。这些不是同一张桌子。
  • 对不起,我的错。这是一张错误的桌子,对不起。现在一定是对的。现在可以查了吗?
  • 表上没有其他东西(触发器或指向它的外键)可以阻止删除?

标签: sql tsql transactions sql-update sql-insert


【解决方案1】:

为什么先删除再插入?更新一下吧。

IF EXISTS(select 1 from DocGenVariable where userkey_sessionid = @key_session 

var_name = @var_name and topic_id = @topic_id) 
BEGIN
    UPDATE ....
    END ELSE BEGIN
    INSERT ... 
END

【讨论】:

  • 已更改为 UPDATE,但这没有帮助。
【解决方案2】:

试试upsert

 using DocGenVariable target 
 using DocGenVariable source  
    on source.userkey_sessionid = @key_session     
   and source.var_name = @var_name     
   and source.topic_id = @topic_id   
   and target.userkey_sessionid = @key_session     
   and target.var_name = @var_name     
   and target.topic_id = @topic_id  
  when match 
       set target.resource_id = @resource_id 
         , target .added = GetDate()   
  when not matched then
       insert into DocGenVariable(userkey_sessionid, is_session, var_name, var_value, topic_id, resource_id, added)
       values (@key_session, @is_session, @var_name, @var_value, @topic_id, @resource_id, GetDate())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多