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
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
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? –
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
Ist Ihre Frage, warum der erste 'IF NOT EXISTS ...' Block ausgeführt wird, der OVC-Datensätze einfügt? –