使用重复的空值更新触发器

时间:2018-11-01 07:16:47

标签: sql sql-server triggers

我创建了一个触发器,该触发器将使用DateTime戳更新文档类型。下面是我的代码

create TRIGGER [dbo].[trg_DocTypeChangeTracking] ON [dbo].[master]
AFTER  UPDATE
AS
declare @MasKey int;
declare @DocType varchar(100);

SET NOCOUNT ON

SELECT @MasKey=(SELECT i.MAS_KEY FROM INSERTED i )
IF ( UPDATE(PASSP_ISU) OR UPDATE(PASSP_EXP))
SET @DocType ='Passport'
IF ( UPDATE(RES_ISU) OR UPDATE(RES_EXP))
SET @DocType ='Residency'
IF ( UPDATE(LAB_ID_ISU) OR UPDATE(LAB_ID_EXP))
SET @DocType ='LaborID'
IF ( UPDATE(Emirates_ID_Issue_Date) OR UPDATE(Emirates_ID_Expiry_Date))
SET @DocType ='EmiratesID'
BEGIN
INSERT dbo.tblDocTypeChangeTracking
(
    MasKey,
    DocType,
    DateModified
)
SELECT @MasKey,@DocType,GETDATE() 
END

问题是,当更新任何到期日时,它将在具有空值的跟踪表中插入记录。我只需要在同一日期为每个doctype创建一条记录。如何解决此问题。

ID  Mas_Key DocType DateModified
1   NULL    NULL    2018-11-01
2   NULL    NULL    2018-11-01
3   NULL    NULL    2018-11-01
4   NULL    NULL    2018-11-01
5   73  Passport    2018-11-01

enter image description here

1 个答案:

答案 0 :(得分:1)

您需要编写一个可用于 sets 的查询,而不是尝试按程序进行操作。 inserteddeleted是伪表,其包含的行数与触发触发器的操作所影响的行数相同。这很容易超过 1 。另外,UPDATE()回答了一个与我想问的问题不同的问题(它只是有效地告诉您SET子句中是否提到了该列,而不是值是否已更改)。 / p>

所以,我会写类似的东西:

create TRIGGER [dbo].[trg_DocTypeChangeTracking] ON [dbo].[master]
AFTER  UPDATE
AS
declare @MasKey int;
declare @DocType varchar(100);

SET NOCOUNT ON

INSERT dbo.tblDocTypeChangeTracking
(
    MasKey,
    DocType,
    DateModified
)
SELECT
    i.mas_key,
    DocType,
    GETDATE()
from
    inserted i
        inner join
    deleted d
        on
            i.mas_key = d.mas_key
        cross join
    (values(1,'Passport'), (2,'Residency')) t(ID,DocType)
where
    (t.ID = 1 and i.passp_isu != d.passp_isu) or
    (t.ID = 2 and i.res_isu != d.res_isu)

您还将注意到,如果passp_isures_isu在任何特定行中都发生了更改,我们将产生行以插入到{{1} }。

现在,由于两个原因,以上内容并不完整。首先,我尚未列出每个tblDocTypeChangeTracking或每个DocType的所有条件-我将其作为练习留给您。另外,我假设DocType等不可为空,并且/或者我们不需要检测passp_isu-> null的变化(反之亦然)。在标准SQL中,我将能够编写not null来执行“ i.passp_isu is different from d.passp_isu感知”差异检查。不幸的是,在SQL Server中,尚不支持此功能,因此,如果需要支持此类检查,则需要将每个比较写为:

null

哪个漂亮得多