更新时SQL违反主键约束

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了更新时SQL违反主键约束相关的知识,希望对你有一定的参考价值。

--EDITED--

我想我弄明白了这个问题。原始行正在更新而不是最新行,因此CreationDate是相同的,因为ID + CreationDate是主键,它返回违规。更新记录时有没有办法选择最新的行而不是原始行?

感谢:D

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

enter image description here

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

我可以添加'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'
答案

您是否在历史记录表上记录了一个事务?因此,您需要删除历史记录表的唯一ID。只有TransactionID INT,而不是身份,你的问题是因为每次执行UPDATE时,记录都被插入到历史表中,所以如果记录已经存在意味着说,如果ID已经存在于历史表中,那么你不允许插入相同的ID,这就是您将收到该错误的原因。

以上是关于更新时SQL违反主键约束的主要内容,如果未能解决你的问题,请参考以下文章

主键对数据更新的影响

java.sql.SQLException: ORA-00001: 违反唯一约束条件 (SCOTT.SYS_C0011456)

尽管记录不存在,但 SQL 主键约束

违反 PRIMARY KEY 约束

代码第一个数据库:SqlException:违反主键约束“PK_dbo.PrivatKasses”。

Hibernate主键生成策略strategy = "increment"报错违反唯一性约束