【问题标题】:SQL violation of Primary Key constraint on update更新时 SQL 违反主键约束
【发布时间】:2015-10-07 01:45:13
【问题描述】:

--已编辑--

我想我找到了问题所在。正在更新原始行而不是最新行,因此 CreationDate 是相同的,并且由于 ID + CreationDate 是主键,因此它返回违规。更新记录时有什么办法可以选择最新的行而不是原来的行?

谢谢:D

----------------

我得到了违反主键约束的错误,但我不知道为什么,因为我的主键值是唯一的。

我可以添加“Darren”的记录并更新一次。之后我得到错误。我的触发器的工作原理是,当我更新现有记录时,原始记录和编辑记录都插入到表 ProcessList 中,以便我能够看到对所有记录所做的所有更改。

表格:

CREATE TABLE dbo.ProcessList
(
    TransactionID       integer         IDENTITY,
    IsEdited            bit             DEFAULT 'FALSE',
    ID                  integer         NOT NULL,
    Name                varchar(30)     NOT NULL,
    Amount              smallmoney      NOT NULL,
    CreationDate        datetime        DEFAULT GETDATE(),
    ModificationDate    datetime,
    PRIMARY KEY (ID, CreationDate)
)

CREATE TABLE dbo.ProcessListHist
(
    TransactionID       integer         IDENTITY,
    IsEdited            bit             DEFAULT 'FALSE',
    ID                  integer         NOT NULL,
    Name                varchar(30)     NOT NULL,
    Amount              smallmoney      NOT NULL,
    CreationDate        datetime        DEFAULT GETDATE(),
    ModificationDate    datetime,
    PRIMARY KEY (ID, CreationDate)
)

触发器:

CREATE TRIGGER CloneAfterUpdate ON ProcessList
AFTER UPDATE
AS
    IF (UPDATE (Amount) OR UPDATE (NAME))
    BEGIN
        INSERT INTO ProcessListHist (ID, Name, Amount, CreationDate, ModificationDate, IsEdited)
            SELECT 
                ID, Name, Amount, CreationDate, GETDATE(), 'True'
            FROM deleted

        UPDATE PL
        SET PL.CreationDate = PLH.ModificationDate
        FROM ProcessList PL
        INNER JOIN deleted ON PL.ID = deleted.ID 
                           AND PL.CreationDate = deleted.CreationDate
        INNER JOIN ProcessListHist PLH ON PL.ID = PLH.ID 
                                       AND PLH.CreationDate = deleted.CreationDate

        INSERT INTO ProcessList (ID, Name, Amount, CreationDate, ModificationDate, IsEdited)
            SELECT 
                ID, Name, Amount, CreationDate, ModificationDate, IsEdited
            FROM ProcessListHist
END

插入/更新语句:

INSERT INTO ProcessList (ID, Name, Amount) VALUES ('1020', 'Darren', '300')
UPDATE ProcessList SET Amount = 1000 WHERE Name = 'Darren'

【问题讨论】:

  • 如果没有NULL id,你能检查你的表记录吗?

标签: sql sql-server key


【解决方案1】:

您在历史记录表上记录交易对吗? ,因此您需要删除历史表的 ID 唯一性。只设置TransactionID INT,不是身份,你的问题是因为每次执行UPDATE,记录都会插入到历史表中,所以如果记录已经存在意思是说,如果ID已经存在于历史表中,您不能插入相同的 ID,这就是您会收到该错误的原因。

【讨论】:

  • 我试过了,还是不行。仍然返回相同的错误。
  • @eyeballs,你在你的两张桌子上试过了吗? ProcessListProcessListHist ,删除 ID 的唯一性.. 使其仅 INT.. 这样当触发器触发并且 INSERT 语句在历史表中检测到相同的 ID 时,它仍然会插入。
  • 哦,但我需要身份,以便 transactionID 是唯一的并且可以用于跟踪记录:
  • @eyeballs ,您仍然可以插入 TransactionID 但不是唯一的,因为您正在执行更新记录,更新记录将在历史表中插入相同的 transactionid,所以如果您的事务 id 是唯一的(身份) , 会报错,但是如果你的id没有定义为唯一的,你仍然可以插入相同的id而不会出错。
猜你喜欢
  • 1970-01-01
  • 2021-04-11
  • 2016-08-24
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
  • 2012-07-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多