Обновить триггер с повторяющимися нулевыми значениями - PullRequest
0 голосов
/ 01 ноября 2018

Я создал триггер, который обновит тип документа со штампом 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

Проблема в том, что при обновлении какой-либо даты истечения она вставляет записи в таблицу отслеживания с нулевыми значениями. Мне просто нужна одна запись на каждый тип документа в тот же день. как решить эту проблему.

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 голосов
/ 01 ноября 2018

Вам нужно написать запрос, который работает с множествами , а не пытаться делать что-то процедурно. inserted и deleted - это псевдо-таблицы, содержащие столько строк, сколько было затронуто операцией, вызвавшей срабатывание триггера. Это может быть легко больше чем 1 . Кроме того, UPDATE() отвечает на вопрос, отличный от того, что, я думаю, вы пытаетесь задать (он просто эффективно сообщает, упоминался ли этот столбец в предложении SET, а не изменилось ли значение).

Итак, я бы написал что-то вроде:

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_isu, и res_isu изменились в какой-либо конкретной строке, мы создаем две строки для вставки в tblDocTypeChangeTracking.

Теперь вышесказанное является неполным по двум причинам. Во-первых, я еще не перечислил все условия для каждого DocType или для каждого DocType - я оставляю это как упражнение для вас. Кроме того, я предположил, что passp_isu и т. Д. Не обнуляются и / или нам не нужно обнаруживать null -> not null изменений (и наоборот). В стандартном SQL я мог бы написать i.passp_isu is different from d.passp_isu, чтобы выполнить проверку различий "null". К сожалению, в SQL Server это еще не поддерживается, поэтому, если вам нужно поддерживать такие проверки, вам нужно записать каждое сравнение как:

(i.passp_isu != d.passp_isu or
i.passp_isu is null and d.passp_isu is not null or
i.passp_isu is not null and d.passp_isu is null)

Что гораздо менее красиво.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...