更新主键时,如何在更新触发器中匹配插入和删除?

时间:2016-06-03 14:21:28

标签: sql-server triggers sql-server-2008-r2 sql-server-2014 database-trigger

假设一个这样的表:

tblCostCenters
CCID   nvarchar(10) not null primary key
CCDesc nvarchar(100) null 

现在有一个" INSTEAD OF UPDATE"触发此表。 触发器可以使用这些伪表:

  • inserted包含新记录,因为它们应该更新
  • deleted包含更新前的旧记录

现在,如果用户想要更新主键,会发生什么?

假设这句话:

UPDATE tblCostCenters set CCID='new' where CCID='old' ;

由于主键本身已更改,触发器如何匹配deletedinserted之间的记录以找出应更新的记录?

3 个答案:

答案 0 :(得分:3)

这没有神奇的伎俩 - 你只有inserteddeleted行来建立你的匹配。虽然我知道有(非常罕见的)更新PK可能有意义的情况(是的,是更新PK值的方法),你必须预测这样的情况并利用某种形式的备用密钥,这样即使PK更改也可以匹配行。

因此,如果你是PK是唯一的方式来唯一识别记录,那么当你改变时,你就会失去运气。如果您有另一个唯一约束(可用作备用键),那么只要PK更新就必须使用它。

总之,如果您要允许PK更改,我强烈建议您实施这种"备份密钥"处理这种情况和任何其他类似情况,并尽可能地限制首先发生这种情况的情况。

答案 1 :(得分:2)

你不能更新"主键。主键IS记录本身。你所做的工作 - 正在删除"未修改的pk"并插入新的"修改的pk"。通过这种方式,可以清楚删除哪些记录以及插入哪些记录。

答案 2 :(得分:0)

要在@xdd answer上展开一点,这里有一些代码:

-- Find out [PK]s that have been "added"
SELECT [PK]
INTO #ToInsert
FROM inserted
EXCEPT
SELECT [PK]
FROM deleted

-- Find out [PK]s that have been "deleted"
SELECT [PK]
INTO #ToDelete
FROM deleted
EXCEPT
SELECT [PK]
FROM inserted

-- Change PK by deleting all records where PK is no longer present 
-- and then inserting them as new records
DELETE FROM [Table]
WHERE [PK] IN( SELECT [PK] FROM #ToDelete )    

INSERT INTO [Table]
SELECT *
FROM inserted
WHERE [PK] IN( SELECT [PK] FROM #ToInsert )



-- Update the rest of the data
UPDATE a
SET col1 = I.col1,
    col2 = I.col2,
    ...
FROM [Table] AS a
    INNER JOIN inserted AS I ON a.[PK] = I.[PK]
WHERE I.PK NOT IN( SELECT [PK] FROM #ToInsert )
    AND I.PK NOT IN( SELECT [PK] FROM #ToDelete )

请注意,概念上不需要上次更新,因为您可以简单地进行更新 DELETE所有deletedINSERT所有inserted IDENTITY 需要实际更新的唯一情况是,当您拥有/* ----------- iPhone 4 and 4S ----------- */ /* Portrait and Landscape */ @media only screen and (min-device-width: 320px) and (max-device-width: 480px) and (-webkit-min-device-pixel-ratio: 2) { } /* Portrait */ @media only screen and (min-device-width: 320px) and (max-device-width: 480px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait) { } /* Landscape */ @media only screen and (min-device-width: 320px) and (max-device-width: 480px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: landscape) { } /* ----------- iPhone 5 and 5S ----------- */ /* Portrait and Landscape */ @media only screen and (min-device-width: 320px) and (max-device-width: 568px) and (-webkit-min-device-pixel-ratio: 2) { } /* Portrait */ @media only screen and (min-device-width: 320px) and (max-device-width: 568px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait) { } /* Landscape */ @media only screen and (min-device-width: 320px) and (max-device-width: 568px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: landscape) { } /* ----------- iPhone 6 ----------- */ /* Portrait and Landscape */ @media only screen and (min-device-width: 375px) and (max-device-width: 667px) and (-webkit-min-device-pixel-ratio: 2) { } /* Portrait */ @media only screen and (min-device-width: 375px) and (max-device-width: 667px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait) { } /* Landscape */ @media only screen and (min-device-width: 375px) and (max-device-width: 667px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: landscape) { } /* ----------- iPhone 6+ ----------- */ /* Portrait and Landscape */ @media only screen and (min-device-width: 414px) and (max-device-width: 736px) and (-webkit-min-device-pixel-ratio: 3) { } /* Portrait */ @media only screen and (min-device-width: 414px) and (max-device-width: 736px) and (-webkit-min-device-pixel-ratio: 3) and (orientation: portrait) { } /* Landscape */ @media only screen and (min-device-width: 414px) and (max-device-width: 736px) and (-webkit-min-device-pixel-ratio: 3) and (orientation: landscape) { } /* ----------- Galaxy S3 ----------- */ /* Portrait and Landscape */ @media screen and (device-width: 320px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 2) { } /* Portrait */ @media screen and (device-width: 320px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait) { } /* Landscape */ @media screen and (device-width: 320px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape) { } /* ----------- Galaxy S4 ----------- */ /* Portrait and Landscape */ @media screen and (device-width: 320px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 3) { } /* Portrait */ @media screen and (device-width: 320px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait) { } /* Landscape */ @media screen and (device-width: 320px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape) { } /* ----------- Galaxy S5 ----------- */ /* Portrait and Landscape */ @media screen and (device-width: 360px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 3) { } /* Portrait */ @media screen and (device-width: 360px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait) { } /* Landscape */ @media screen and (device-width: 360px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape) { } /* ----------- HTC One ----------- */ /* Portrait and Landscape */ @media screen and (device-width: 360px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 3) { } /* Portrait */ @media screen and (device-width: 360px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait) { } /* Landscape */ @media screen and (device-width: 360px) and (device-height: 640px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape) { } /* ----------- iPad mini ----------- */ /* Portrait and Landscape */ @media only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (-webkit-min-device-pixel-ratio: 1) { } /* Portrait */ @media only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: portrait) and (-webkit-min-device-pixel-ratio: 1) { } /* Landscape */ @media only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: landscape) and (-webkit-min-device-pixel-ratio: 1) { } /* ----------- iPad 1 and 2 ----------- */ /* Portrait and Landscape */ @media only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (-webkit-min-device-pixel-ratio: 1) { } /* Portrait */ @media only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: portrait) and (-webkit-min-device-pixel-ratio: 1) { } /* Landscape */ @media only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: landscape) and (-webkit-min-device-pixel-ratio: 1) { } /* ----------- iPad 3 and 4 ----------- */ /* Portrait and Landscape */ @media only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (-webkit-min-device-pixel-ratio: 2) { } /* Portrait */ @media only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: portrait) and (-webkit-min-device-pixel-ratio: 2) { } /* Landscape */ @media only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: landscape) and (-webkit-min-device-pixel-ratio: 2) { } /* ----------- Galaxy Tab 10.1 ----------- */ /* Portrait and Landscape */ @media (min-device-width: 800px) and (max-device-width: 1280px) { } /* Portrait */ @media (max-device-width: 800px) and (orientation: portrait) { } /* Landscape */ @media (max-device-width: 1280px) and (orientation: landscape) { } /* ----------- Asus Nexus 7 ----------- */ /* Portrait and Landscape */ @media screen and (device-width: 601px) and (device-height: 906px) and (-webkit-min-device-pixel-ratio: 1.331) and (-webkit-max-device-pixel-ratio: 1.332) { } /* Portrait */ @media screen and (device-width: 601px) and (device-height: 906px) and (-webkit-min-device-pixel-ratio: 1.331) and (-webkit-max-device-pixel-ratio: 1.332) and (orientation: portrait) { } /* Landscape */ @media screen and (device-width: 601px) and (device-height: 906px) and (-webkit-min-device-pixel-ratio: 1.331) and (-webkit-max-device-pixel-ratio: 1.332) and (orientation: landscape) { } /* ----------- Kindle Fire HD 7" ----------- */ /* Portrait and Landscape */ @media only screen and (min-device-width: 800px) and (max-device-width: 1280px) and (-webkit-min-device-pixel-ratio: 1.5) { } /* Portrait */ @media only screen and (min-device-width: 800px) and (max-device-width: 1280px) and (-webkit-min-device-pixel-ratio: 1.5) and (orientation: portrait) { } /* Landscape */ @media only screen and (min-device-width: 800px) and (max-device-width: 1280px) and (-webkit-min-device-pixel-ratio: 1.5) and (orientation: landscape) { } /* ----------- Kindle Fire HD 8.9" ----------- */ /* Portrait and Landscape */ @media only screen and (min-device-width: 1200px) and (max-device-width: 1600px) and (-webkit-min-device-pixel-ratio: 1.5) { } /* Portrait */ @media only screen and (min-device-width: 1200px) and (max-device-width: 1600px) and (-webkit-min-device-pixel-ratio: 1.5) and (orientation: portrait) { } /* Landscape */ @media only screen and (min-device-width: 1200px) and (max-device-width: 1600px) and (-webkit-min-device-pixel-ratio: 1.5) and (orientation: landscape) { } /* ----------- Non-Retina Screens ----------- */ @media screen and (min-device-width: 1200px) and (max-device-width: 1600px) and (-webkit-min-device-pixel-ratio: 1) { } /* ----------- Retina Screens ----------- */ @media screen and (min-device-width: 1200px) and (max-device-width: 1600px) and (-webkit-min-device-pixel-ratio: 2) and (min-resolution: 192dpi) { } /* ----------- Apple Watch ----------- */ @media (max-device-width: 42mm) and (min-device-width: 38mm) { } /* ----------- Moto 360 Watch ----------- */ @media (max-device-width: 218px) and (max-device-height: 281px) { } PK列并且您不想更改它时。