myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Datentechnologien » [gelöst] Trigger: Mehrere IF UPDATE(column) im Trigger
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

[gelöst] Trigger: Mehrere IF UPDATE(column) im Trigger

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Gurrnder
myCSharp.de-Mitglied

Dabei seit: 08.08.2007
Beiträge: 142


Gurrnder ist offline

[gelöst] Trigger: Mehrere IF UPDATE(column) im Trigger

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

verwendetes Datenbanksystem: MS SQL Server 2008

Hallo Zusammen

Ich habe eine history Tabelle, welche ich bei Insert und Update mit einem Trigger befülle. Soweit die Theorie. Hier gleich mal der Trigger-Code:
CODE Deleted

Mache ich nun ein Update auf die mit Triggern versehene Tabelle, wird nur ein einziges der IF UPDATE(column) Statements ausgefürht. Alle weiteren schweigen.
Es schaut so aus, als würde nur das ERSTE ausgeführt und der Trigger dann verlassen.
Mit erste meine ich die Reihenfolge im Update Query.

Code:
1:
2:
3:
4:
5:
6:
update tbl_Equipment
set ID_Status = same,
ID_Agreement = same,
NetbiosName = NEW, 
Note = NEW
where ID_Equipment = ID

Obiger Code sollte mir also 2 einträge in der History tabelle bescheren, ich erhalte aber nur einen. Nämlich den NetbiosName wechsel. Note wird Ignoriert!

Woran liegt das? Und wie kann ich dieses Problem Lösen?

Freundlichst

Gurrnder




ps. Kann man den CODE tag irgendwie in der Höhe beschränken?

Dieser Beitrag wurde 5 mal editiert, zum letzten Mal von Gurrnder am 26.08.2009 16:37.

Neuer Beitrag 26.08.2009 14:29 Beiträge des Benutzers | zu Buddylist hinzufügen
Florian Reischl Florian Reischl ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2880.jpg


Dabei seit: 16.10.2007
Beiträge: 1.564
Entwicklungsumgebung: Visual Studio * | SQL Server *
Herkunft: München


Florian Reischl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Gurrnder

Ich kann so keinen Feher feststellen. Bis du sicher dass du neue Werte in die Spalten NetbiosName und Note einfügst?

Kommentiere testweise mal alles außer dem UPDATE für die Note Spalte in deinem Trigger aus und versuch's noch mal.

Hier ein Beispiel das ich gerade mal getestet habe welches funktioniert:

Code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
---========================================================
-- Test Tabelle 
IF (OBJECT_ID('TestTrigger') IS NULL)
   CREATE TABLE TestTrigger
   (
      Id INT NOT NULL IDENTITY PRIMARY KEY CLUSTERED,
      SomeInt INT,
      SomeVarChar VARCHAR(30)
   );
GO
---========================================================
-- Hist Tabelle
IF (OBJECT_ID('TestTrigger_Hist') IS NULL)
   CREATE TABLE TestTrigger_Hist
   (
      Id INT NOT NULL IDENTITY PRIMARY KEY CLUSTERED,
      ObjectId INT NOT NULL,
      ValueOld VARCHAR(100),
      ValueNew VARCHAR(100)
   );
GO
---========================================================
-- Trigger to handle auditing
IF (OBJECT_ID('TR_TestTrigger_Hist') IS NULL)
   EXECUTE ('CREATE TRIGGER TR_TestTrigger_Hist ON TestTrigger FOR UPDATE AS DECLARE @i INT')
GO
ALTER TRIGGER TR_TestTrigger_Hist ON TestTrigger
   FOR UPDATE
AS

-- Update for SomeInt
IF (UPDATE(SomeInt))
BEGIN
   INSERT INTO TestTrigger_Hist (
         ValueOld
         ,ValueNew
         ,ObjectId
         )
      SELECT
         CONVERT(VARCHAR(100), d.SomeInt)
         ,CONVERT(VARCHAR(100), i.SomeInt)
         ,i.Id
      FROM inserted i
         JOIN deleted d ON i.Id = d.Id;
END

-- Update for SomeVarChar
IF (UPDATE(SomeVarChar))
BEGIN
   INSERT INTO TestTrigger_Hist (
         ValueOld
         ,ValueNew
         ,ObjectId
         )
      SELECT
         d.SomeVarChar
         ,i.SomeVarChar
         ,i.Id
      FROM inserted i
         JOIN deleted d ON i.Id = d.Id;
END
GO
---========================================================
-- Insert one sample row
INSERT INTO TestTrigger
   SELECT 1, 'Blah'

-- Get new Id
DECLARE @Id INT   = SCOPE_IDENTITY();

-- Update two columns
UPDATE TestTrigger SET 
      SomeInt = 2, 
      SomeVarChar = 'Bluff' 
   WHERE Id = @Id

-- Show history result
SELECT * 
   FROM TestTrigger_Hist 
   WHERE ObjectId = @Id

Grüße
Flo
Neuer Beitrag 26.08.2009 15:08 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Gurrnder
myCSharp.de-Mitglied

Dabei seit: 08.08.2007
Beiträge: 142

Themenstarter Thema begonnen von Gurrnder

Gurrnder ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Bahnbrechende neuigkeiten.

Wenn ich das Update Command direkt am Management Studio abfeuere, funktioniert der Trigger einwand frei.
Wird das Command aber aus C# heraus ausgeführt, wird nur die erste veränderte spalte historysiert ... gespeichert werden aber alle Änderungen!

Problem gefunden, Beschreibung Folgt:

Also. Wenn ich ein Feld von x auf y update, funktioniert die sache.
Ist ein feld aber NULL und wird auf x gesetzt, taucht dies nicht in der History auf.

NULL --> 'etwas' wird also von IF UPDATE() nicht als update erkannt und desswegen nicht bearbeitet.

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Gurrnder am 26.08.2009 16:06.

Neuer Beitrag 26.08.2009 15:46 Beiträge des Benutzers | zu Buddylist hinzufügen
Florian Reischl Florian Reischl ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2880.jpg


Dabei seit: 16.10.2007
Beiträge: 1.564
Entwicklungsumgebung: Visual Studio * | SQL Server *
Herkunft: München


Florian Reischl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Nein. UPDATE() funktioniert (natürlich!) auch bei NULL Werten. Hättest du deinen Trigger jetzt nicht gelöscht (warum eigentlich??) hätte ich dir den Fehler zeigen können. Du kannst NULL Werte nicht mit "=" vergleichen. Du musst "ISNULL" oder "IS NULL" verwenden.
Neuer Beitrag 26.08.2009 16:14 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Gurrnder
myCSharp.de-Mitglied

Dabei seit: 08.08.2007
Beiträge: 142

Themenstarter Thema begonnen von Gurrnder

Gurrnder ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
USE [Harem]
GO

/****** Object:  Trigger [dbo].[tr_History_Update]    Script Date: 08/26/2009 09:57:44 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

ALTER TRIGGER [dbo].[tr_History_Update]
   on [dbo].[tbl_Equipment]
   for update
AS 
BEGIN
SET NOCOUNT ON;
	if (update([ID_Equipment]) )
	begin
		insert into dbo.tbl_History 
		(ID_ConcernedEntry, ValueOld, ValueNew, ConcernedField, ConcernedTable, ID_HistoryType, LoginName, [TimeStamp])
		(select i.[ID_Equipment] as ID_ConcernedEntry, 
			cast(d.[ID_Equipment] as varchar(8000)) as ValueOld, 
			cast(i.[ID_Equipment] as varchar(8000)) as ValueNew,
			'ID_Equipment' as ConcernedField,
			'tbl_Equipment' as ConcernedTable,
			2 as ID_HistoryType,
			SYSTEM_USER as LoginName,
			getdate() as TimeStamp
		from Inserted i 
		join Deleted d on i.[ID_Equipment] = d.[ID_Equipment]
		where i.[ID_Equipment] != d.[ID_Equipment])
	end

	if (update([ID_Status]) )
	begin
		insert into dbo.tbl_History 
		(ID_ConcernedEntry, ValueOld, ValueNew, ConcernedField, ConcernedTable, ID_HistoryType, LoginName, [TimeStamp])
		(select i.[ID_Equipment] as ID_ConcernedEntry, 
			cast(d.[ID_Status] as varchar(8000)) as ValueOld, 
			cast(i.[ID_Status] as varchar(8000)) as ValueNew,
			'ID_Status' as ConcernedField,
			'tbl_Equipment' as ConcernedTable,
			2 as ID_HistoryType,
			SYSTEM_USER as LoginName,
			getdate() as TimeStamp
		from Inserted i 
		join Deleted d on i.[ID_Equipment] = d.[ID_Equipment]
		where i.[ID_Status] != d.[ID_Status])
	end

	if (update([ID_Agreement]) )
	begin
		insert into dbo.tbl_History 
		(ID_ConcernedEntry, ValueOld, ValueNew, ConcernedField, ConcernedTable, ID_HistoryType, LoginName, [TimeStamp])
		(select i.[ID_Equipment] as ID_ConcernedEntry, 
			cast(d.[ID_Agreement] as varchar(8000)) as ValueOld, 
			cast(i.[ID_Agreement] as varchar(8000)) as ValueNew,
			'ID_Agreement' as ConcernedField,
			'tbl_Equipment' as ConcernedTable,
			2 as ID_HistoryType,
			SYSTEM_USER as LoginName,
			getdate() as TimeStamp
		from Inserted i 
		join Deleted d on i.[ID_Equipment] = d.[ID_Equipment]
		where i.[ID_Agreement] != d.[ID_Agreement])
	end

	if (update([ID_EquipmentModel]) )
	begin
		insert into dbo.tbl_History 
		(ID_ConcernedEntry, ValueOld, ValueNew, ConcernedField, ConcernedTable, ID_HistoryType, LoginName, [TimeStamp])
		(select i.[ID_Equipment] as ID_ConcernedEntry, 
			cast(d.[ID_EquipmentModel] as varchar(8000)) as ValueOld, 
			cast(i.[ID_EquipmentModel] as varchar(8000)) as ValueNew,
			'ID_EquipmentModel' as ConcernedField,
			'tbl_Equipment' as ConcernedTable,
			2 as ID_HistoryType,
			SYSTEM_USER as LoginName,
			getdate() as TimeStamp
		from Inserted i 
		join Deleted d on i.[ID_Equipment] = d.[ID_Equipment]
		where i.[ID_EquipmentModel] != d.[ID_EquipmentModel])
	end

	if (update([DeviceNo]) )
	begin
		insert into dbo.tbl_History 
		(ID_ConcernedEntry, ValueOld, ValueNew, ConcernedField, ConcernedTable, ID_HistoryType, LoginName, [TimeStamp])
		(select i.[ID_Equipment] as ID_ConcernedEntry, 
			cast(d.[DeviceNo] as varchar(8000)) as ValueOld, 
			cast(i.[DeviceNo] as varchar(8000)) as ValueNew,
			'DeviceNo' as ConcernedField,
			'tbl_Equipment' as ConcernedTable,
			2 as ID_HistoryType,
			SYSTEM_USER as LoginName,
			getdate() as TimeStamp
		from Inserted i 
		join Deleted d on i.[ID_Equipment] = d.[ID_Equipment]
		where i.[DeviceNo] != d.[DeviceNo])
	end

	if (update([DateOfPurchase]) )
	begin
		insert into dbo.tbl_History 
		(ID_ConcernedEntry, ValueOld, ValueNew, ConcernedField, ConcernedTable, ID_HistoryType, LoginName, [TimeStamp])
		(select i.[ID_Equipment] as ID_ConcernedEntry, 
			cast(d.[DateOfPurchase] as varchar(8000)) as ValueOld, 
			cast(i.[DateOfPurchase] as varchar(8000)) as ValueNew,
			'DateOfPurchase' as ConcernedField,
			'tbl_Equipment' as ConcernedTable,
			2 as ID_HistoryType,
			SYSTEM_USER as LoginName,
			getdate() as TimeStamp
		from Inserted i 
		join Deleted d on i.[ID_Equipment] = d.[ID_Equipment]
		where i.[DateOfPurchase] != d.[DateOfPurchase])
	end

	if (update([ExpiryOfWarranty]) )
	begin
		insert into dbo.tbl_History 
		(ID_ConcernedEntry, ValueOld, ValueNew, ConcernedField, ConcernedTable, ID_HistoryType, LoginName, [TimeStamp])
		(select i.[ID_Equipment] as ID_ConcernedEntry, 
			cast(d.[ExpiryOfWarranty] as varchar(8000)) as ValueOld, 
			cast(i.[ExpiryOfWarranty] as varchar(8000)) as ValueNew,
			'ExpiryOfWarranty' as ConcernedField,
			'tbl_Equipment' as ConcernedTable,
			2 as ID_HistoryType,
			SYSTEM_USER as LoginName,
			getdate() as TimeStamp
		from Inserted i 
		join Deleted d on i.[ID_Equipment] = d.[ID_Equipment]
		where i.[ExpiryOfWarranty] != d.[ExpiryOfWarranty])
	end

	if (update([NetbiosName]) )
	begin
		insert into dbo.tbl_History 
		(ID_ConcernedEntry, ValueOld, ValueNew, ConcernedField, ConcernedTable, ID_HistoryType, LoginName, [TimeStamp])
		(select i.[ID_Equipment] as ID_ConcernedEntry, 
			cast(d.[NetbiosName] as varchar(8000)) as ValueOld, 
			cast(i.[NetbiosName] as varchar(8000)) as ValueNew,
			'NetbiosName' as ConcernedField,
			'tbl_Equipment' as ConcernedTable,
			2 as ID_HistoryType,
			SYSTEM_USER as LoginName,
			getdate() as TimeStamp
		from Inserted i 
		join Deleted d on i.[ID_Equipment] = d.[ID_Equipment]
		where i.[NetbiosName] != d.[NetbiosName])
	end

	if (update([Note]) )
	begin
		insert into dbo.tbl_History 
		(ID_ConcernedEntry, ValueOld, ValueNew, ConcernedField, ConcernedTable, ID_HistoryType, LoginName, [TimeStamp])
		(select i.[ID_Equipment] as ID_ConcernedEntry, 
			cast(d.[Note] as varchar(8000)) as ValueOld, 
			cast(i.[Note] as varchar(8000)) as ValueNew,
			'Note' as ConcernedField,
			'tbl_Equipment' as ConcernedTable,
			2 as ID_HistoryType,
			SYSTEM_USER as LoginName,
			getdate() as TimeStamp
		from Inserted i 
		join Deleted d on i.[ID_Equipment] = d.[ID_Equipment]
		where i.[Note] != d.[Note])
	end
END

GO
Neuer Beitrag 26.08.2009 16:26 Beiträge des Benutzers | zu Buddylist hinzufügen
Florian Reischl Florian Reischl ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2880.jpg


Dabei seit: 16.10.2007
Beiträge: 1.564
Entwicklungsumgebung: Visual Studio * | SQL Server *
Herkunft: München


Florian Reischl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Du musst NULL Werte gesondert behandeln. NULL ist undefiniert und kann mit "=" nicht verglichen werden.

Im Falle deiner "Note" Spalte musst du die WHERE Klausel wie folgt anpassen:

Code:
1:
2:
3:
4:
5:
-- ...
where 
   i.[Note] != d.[Note] 
   OR (i.Note IS NULL AND d.Note IS NOT NULL)
   OR (i.Note IS NOT NULL AND d.Note IS NULL)

Folgendes Beispiel kannst du 1:1 kopieren und ausführen. Es zeigt, dass weder "=" noch mit "!=" mit NULL verwendet werden kann.

Code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
DECLARE @t TABLE (Col1 INT, Col2 INT)

INSERT INTO @t
             SELECT 1, 1
   UNION ALL SELECT 1, 2
   UNION ALL SELECT 1, NULL
   UNION ALL SELECT NULL, NULL

SELECT * FROM @t WHERE Col1 = Col2
SELECT * FROM @t WHERE Col1 != Col2

Grüße
Flo
Neuer Beitrag 26.08.2009 16:34 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Gurrnder
myCSharp.de-Mitglied

Dabei seit: 08.08.2007
Beiträge: 142

Themenstarter Thema begonnen von Gurrnder

Gurrnder ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Das ich da auf die NULL werte achten muss habe ich total verschwitzt.

Danke für deine Hilfe!
Neuer Beitrag 26.08.2009 16:37 Beiträge des Benutzers | zu Buddylist hinzufügen
Florian Reischl Florian Reischl ist männlich
myCSharp.de-Poweruser/ Experte

avatar-2880.jpg


Dabei seit: 16.10.2007
Beiträge: 1.564
Entwicklungsumgebung: Visual Studio * | SQL Server *
Herkunft: München


Florian Reischl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Immer gerne ;-)
Neuer Beitrag 26.08.2009 16:44 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 11 Jahre.
Der letzte Beitrag ist älter als 11 Jahre.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 20.10.2020 10:56