比较触发器中的字段
因此,我创建了一个触发器,用于比较更新前后的情况,并确定 where 子句中指定的特定字段是否已更改。如果是这样,我会将先前信息的快照插入到历史表中。
问题是,当字段使用空值创建时(根据业务规则,它是合法的空),并且进行更新时,无法评估字符串是否不等于空值。我想捕捉到它发送给我们的是空的,后来被填充。
我应该使用什么方法来比较空字段而不影响性能?
这是针对 SQL Server 2005
CREATE TRIGGER [prj].[TRG_Master_Projection_Upd_History] ON [prj].[Master_Projections]
AFTER UPDATE
AS
SET NOCOUNT ON -- Prevents the error that gets thrown after inserting multiple records
-- if multiple records are being updated
BEGIN
INSERT INTO prj.History_Projections (ProjectionID, Cancelled, Appeal, Description, Response_PatternID,
Proj_Mail_date, [3602_Mail_Date], Proj_Qty, [3602_Qty], Proj_Resp_Rate,
Bounce_Back, Nickels, Kits, Oversized_RE, ChangeComments,
Modification_Process, Modification_Date, Modification_User)
SELECT D.ProjectionID, D.Cancelled, D.Appeal, D.Description, D.Response_PatternID, D.Proj_Mail_Date,
D.[3602_Mail_Date], D.Proj_Qty, D.[3602_Qty], D.Proj_Resp_Rate, D.Bounce_Back, D.Nickels, D.Kits,
D.Oversized_RE, D.ChangeComments, D.Modification_Process, D.Modification_Date, D.Modification_User
FROM deleted as D
JOIN inserted as I
ON D.ProjectionID = I.ProjectionID
WHERE (I.Cancelled <> D.Cancelled
OR I.Appeal <> D.Appeal
OR I.Description <> D.Description
OR I.Response_PatternID <> D.Response_PatternID
OR I.Proj_Mail_Date <> D.Proj_Mail_Date
OR I.[3602_Mail_Date] <> D.[3602_Mail_Date]
OR I.Proj_Qty <> D.Proj_Qty
OR I.[3602_Qty] <> D.[3602_Qty]
OR I.Proj_Resp_Rate <> D.Proj_Resp_Rate
OR I.Bounce_Back <> D.Bounce_Back
OR I.Nickels <> D.Nickels
OR I.Kits <> D.Kits
OR I.Oversized_RE <> D.Oversized_RE )
END;
SET NOCOUNT OFF;
So I've created a trigger that compares update before and after and determines if specific fields, specified in the where clause, have changed. If so, I insert a snapshot of the prior information into a history table.
The problem is when the field is created with null values (given the business rules, it is legitimately null) and when an update is made, it is unable to evaluate that the string is not equal to the null value. I want to capture that it was sent to us empty and later filled in.
What approach should I use to compare to null fields without impacting performance?
This is for SQL Server 2005
CREATE TRIGGER [prj].[TRG_Master_Projection_Upd_History] ON [prj].[Master_Projections]
AFTER UPDATE
AS
SET NOCOUNT ON -- Prevents the error that gets thrown after inserting multiple records
-- if multiple records are being updated
BEGIN
INSERT INTO prj.History_Projections (ProjectionID, Cancelled, Appeal, Description, Response_PatternID,
Proj_Mail_date, [3602_Mail_Date], Proj_Qty, [3602_Qty], Proj_Resp_Rate,
Bounce_Back, Nickels, Kits, Oversized_RE, ChangeComments,
Modification_Process, Modification_Date, Modification_User)
SELECT D.ProjectionID, D.Cancelled, D.Appeal, D.Description, D.Response_PatternID, D.Proj_Mail_Date,
D.[3602_Mail_Date], D.Proj_Qty, D.[3602_Qty], D.Proj_Resp_Rate, D.Bounce_Back, D.Nickels, D.Kits,
D.Oversized_RE, D.ChangeComments, D.Modification_Process, D.Modification_Date, D.Modification_User
FROM deleted as D
JOIN inserted as I
ON D.ProjectionID = I.ProjectionID
WHERE (I.Cancelled <> D.Cancelled
OR I.Appeal <> D.Appeal
OR I.Description <> D.Description
OR I.Response_PatternID <> D.Response_PatternID
OR I.Proj_Mail_Date <> D.Proj_Mail_Date
OR I.[3602_Mail_Date] <> D.[3602_Mail_Date]
OR I.Proj_Qty <> D.Proj_Qty
OR I.[3602_Qty] <> D.[3602_Qty]
OR I.Proj_Resp_Rate <> D.Proj_Resp_Rate
OR I.Bounce_Back <> D.Bounce_Back
OR I.Nickels <> D.Nickels
OR I.Kits <> D.Kits
OR I.Oversized_RE <> D.Oversized_RE )
END;
SET NOCOUNT OFF;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不幸的是,您确实必须使用哨兵值。不幸的
是,这并没有什么神奇之处:您必须比较每个值才能看到任何差异。
也就是说,您只触及 INSERTED 和 DELETED 表,因此尽管如此糟糕,但主表并未触及。除非您有影响 10000 行的更新,否则它将运行正常。
您也可以使用 OR 来但这很麻烦
我会坚持使用 ISNULL 以避免 COALESCE 出现微妙的数据类型问题
Unfortunately, you really have to use sentinel values
There is no magic unfortunately: you have to compare every value to see any differences.
Saying that, you only touch the INSERTED and DELETED tables so as bad as this is, the main table is not touched. Unless you have update that affect 10000s if rows, it will run OK.
You can use OR too to but this is cumbersome
I'd stick with ISNULL to avoid subtle datatype issues with COALESCE