2017-12-23 10 views
1

Ich bekomme falsche Logik im Trigger. Ich bekomme eine falsche Anzahl von Datensätzen, die nach der Aktualisierung in der Basistabelle in die Audit-Tabelle eingefügt wurden. Unten ist das Code-Snippet, um dieses Problem neu zu erstellen.Falsche After-Update-Trigger-Logik

create table #T1 (id int NOT NULL, CODE varchar(3) NOT NULL, pkID INT NOT NULL) 
insert into #T1 (id, CODE, pkID) 
values(1, 'vak', 1989),(2,'Vl2',1988), (2,'Vl2',1988)--, (null, 'Gotik') 
go 

create table #T2 (id int NOT NULL, CODE varchar(3) NOT NULL, pkID INT NOT NULL) 
insert into #T2 (id, CODE, pkID) 
values(101, 'vas', 1979),(105,'va3',1973), (4,'va5',1888), (4,'va5',1888)--, (null, 'Popik') 
go 

create table [MyDB].dbo.Test_Dec22nd2017 (id int NOT null CONSTRAINT PK_TEST PRIMARY KEY, Ln varchar(10) null) 
insert into [MyDB].dbo.Test_Dec22nd2017 (id, ln) 

values (1, 'vasya1'),(2,'vasya3'), (4,'vasya2'),(5,'Super'), (6,'LYAYA'), (105,'TERSDF'), (101,'DFSDS') 
go 


DROP TRIGGER DBO.TR_TEST_DEC22nd2017 
GO 
CREATE TRIGGER DBO.TR_TEST_DEC22nd2017 
ON [dbo].[Test_Dec22nd2017] AFTER INSERT, DELETE, UPDATE 
    NOT FOR REPLICATION 

AS 
BEGIN 

    IF NOT EXISTS (SELECT TOP 1 1 FROM 
           inserted ins 
        FULL OUTER JOIN deleted del ON ins.ID = del.ID 
        INNER JOIN 
        [MyDB].dbo.Test_Dec22nd2017 a ON a.id = ISNULL(ins.ID, del.ID) 
        INNER JOIN #T1 t ON t.id = a.id 
        LEFT JOIN #T2 t2 ON t2.id = a.id 
        --WHERE t.id IS NULL AND t2.id IS NULL 
       ) 

     BEGIN 

      WITH CTE2 AS (
        SELECT 
         ISNULL(ins.ID, del.ID) AS ID, 
         CASE 
          WHEN ins.ID IS NOT NULL AND del.ID IS NOT NULL THEN 'UPDATE' 
          WHEN ins.ID IS NOT NULL THEN 'INSERT' 
          ELSE 'UPDATE' END 
         AS AuditType 
        FROM inserted ins 
        FULL OUTER JOIN deleted del 
          ON ins.ID = del.ID 
        ) 

      ,AUDIT_CTE2 AS ( 
        SELECT DISTINCT  
         CTE2.ID, 
         'OVC' AS Code, 
         CTE2.AuditType 
        FROM CTE2 
        -- WHERE ID IS NOT NULL 
         ) 

        INSERT [MyDB].[dbo].[AuditTable] (Code, ID, AuditType)/*, ParentCode, ParentID)*/ 
        SELECT 
         Code, 
         ID, 
         AuditType 
        FROM AUDIT_CTE2 
     END 

    IF EXISTS (SELECT TOP 1 1 FROM 
           inserted ins -- ISNULL(T.pkID, t2.pkID) 
        FULL OUTER JOIN deleted del ON ins.ID = del.ID 
        INNER JOIN 
        [MyDB].dbo.Test_Dec22nd2017 a ON a.id = ISNULL(ins.ID, del.ID) 
        LEFT JOIN #T1 t ON t.id = a.id 
        LEFT JOIN #T2 t2 ON t2.id = a.id 
        WHERE t.id IS NOT NULL OR t2.id IS NOT NULL 
       ) 

     BEGIN 

      WITH CTE AS (
       SELECT 
        ISNULL(ins.ID, del.ID) AS ID, 
        CASE 
         WHEN ins.ID IS NOT NULL AND del.ID IS NOT NULL THEN 'UPDATE' 
         WHEN ins.ID IS NOT NULL THEN 'INSERT' 
         ELSE 'UPDATE' END 
        AS AuditType 
       FROM inserted ins 
       FULL OUTER JOIN deleted del 
         ON ins.ID = del.ID 
         ) 

      ,AUDIT_CTE AS ( 
        SELECT DISTINCT  
         CTE.ID, 
         'TST' AS Code, 
         CTE.AuditType, 
         ISNULL(T.CODE,T2.CODE) AS ParentCode, 
         ISNULL(T.pkID, T2.pkID) AS ParentID 
        FROM CTE 
        INNER JOIN MyDB.dbo.Test_Dec22nd2017 a ON CTE.ID = a.id 
        LEFT OUTER JOIN #T1 T ON T.id = a.id 
        LEFT OUTER JOIN #T2 T2 ON T2.id = a.id 
        WHERE T.pkID IS NOT NULL OR T2.pkID IS NOT NULL 
         ) 

        INSERT [MyDB].[dbo].[AuditTable] (Code, ID, AuditType, ParentCode, ParentID) 
        SELECT 
         Code, 
         ID, 
         AuditType, 
         ParentCode, 
         ParentID 
        FROM AUDIT_CTE 
     END 
END 

Dies ist, was zwei falsche Datensätze in die Audit talbe

GO 
UPDATE [MyDB].dbo.Test_Dec22nd2017 
SET Ln = 'DDD' WHERE ID 
IN (101,105,11) 
SELECT TOP 30 * FROM [MyDB].[dbo].[AuditTable] ORDER BY 1 DESC 

enter image description here

enter image description here

Wie Sie aus den Bildern sehen einzufügen, bewirkt darüber 5 Zeilen einfügen in die Such-Audit-Tabelle. Aber sollte nur 3. für ID 6 mit Eltern Code = Null und ParentID = NULL und zwei Datensätze für ID 101 und 105 mit ParentID von 1973 und 1979 und entsprechende Eltern-Codes einfügen.

Diese beiden Aussagen funktionieren einwandfrei.

insert into [MyDB].dbo.Test_Dec22nd2017 (id, ln) 
values (44,'vasya1'), (45,'vasya2') 
SELECT TOP 30 * FROM [MyDB].[dbo].[AuditTable] ORDER BY 1 DESC 

GO 

UPDATE [MyDB].dbo.Test_Dec22nd2017 
SET Ln = 'DDD' WHERE ID 
IN (5,10,6) 
SELECT TOP 30 * FROM [MyDB].[dbo].[AuditTable] ORDER BY 1 DESC 
+0

von Code ausgeführt habe ich 4 eingefügten Datensätze in die AuditTable, 2 OVC und 2 TST gegen 101 und 105, was richtig ist, wie Sie den Trigger geschrieben haben. Ihr Bild zeigt einen Datensatz, der mit Id 6 gekennzeichnet ist. Wie ist das richtig? –

+0

Tony, für die erste Update-Anweisung, die dieses Problem verursacht, soll der Trigger nur 3 Datensätze wie folgt zurückgeben: 2 Datensätze mit ID 105 und 101 wo ParentID nicht Null ist und einen Datensatz mit ID 6 mit ParentID von NULL. Das Problem hier, dass es auch Datensätze mit ID 105 und 101 mit ParentID von NULL einfügt. – enigma6205

+0

Ist Ihre Frage, warum der erste 'IF NOT EXISTS ...' Block ausgeführt wird, der OVC-Datensätze einfügt? –

Antwort

0

Sie könnten die ersten IF NOT EXISTS in den Trigger ändern: alle IDs zu ignorieren

IF EXISTS (SELECT TOP 1 1 FROM 
       inserted ins 
    FULL OUTER JOIN deleted del ON ins.ID = del.ID 
    INNER JOIN 
    [tempdb].dbo.Test_Dec22nd2017 a ON a.id = ISNULL(ins.ID, del.ID) 
    LEFT JOIN #T1 t ON t.id = a.id 
    LEFT JOIN #T2 t2 ON t2.id = a.id 
    WHERE t.id IS NULL AND t2.id IS NULL 
) 

, die entweder in # T1 existieren oder # T2

+0

Tony, genau das habe ich schon ausprobiert und genau deshalb habe ich diese Frage gepostet. Dies wiederholt nur das Problem. Siehe mein zweites Bild oben mit Zeilen-ID 3 und 4. Ich möchte nicht, dass diese beiden Datensätze in die Audit-Tabelle eingefügt werden. – enigma6205

+0

Haben Sie versucht, mit dem oben genannten zu ersetzen? Es sollte nicht 101 oder 105 mit Patent-ID = NULL einfügen. Das sind diese zwei falschen Zeilen in Ihrem zweiten Bild. Für mich hat es nicht –

+0

Ja, habe ich mit Ihrem Code von oben ersetzt und ich habe 5 Datensätze in die Audit-Tabelle genau so eingefügt, wie es auf dem zweiten Bild erscheint. – enigma6205