Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Trigger mir die Tabelle
Atomroflman
myCSharp.de - Member



Dabei seit:
Beiträge: 266
Herkunft: Hamburg

Themenstarter:

Trigger mir die Tabelle

beantworten | zitieren | melden

verwendetes Datenbanksystem: MSSQL 2008 Express

Hallo ihrs,

ich habe mir einen Datenbank-Trigger angelgt, der automatisch Trigger in einer neuen Tabelle anlegen soll falls diese nicht vorhanden sind.
Allerdings kann ich nun Tabellen nicht mehr ändern weil ich auf einen Fehler laufe, da der Name des Triggers schon vergeben ist.

CREATE TRIGGER [Create_DefaultTriggers]
   ON  DATABASE 
   AFTER CREATE_TABLE
AS 
BEGIN
	DECLARE @data XML;
	SET @data = EVENTDATA();

	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.
	SET NOCOUNT ON;

	DECLARE @TableName varchar(100), @Statement varchar(1000);
	SET @TableName = EVENTDATA().value
        ('(/EVENT_INSTANCE/ObjectName)[1]','varchar(100)');
    -- Insert statements for trigger here
	IF NOT (@TableName LIKE 'System%')
	begin
		BEGIN TRY
			SET @Statement = 
				' CREATE TRIGGER [dbo].[Delete' + @TableName + ']' +
				' ON  [dbo].[' + @TableName + ']' + 
				' INSTEAD OF DELETE AS' + 
				' BEGIN' +
				' SET NOCOUNT ON;' +
				' DELETE FROM [dbo].[' + @TableName + '] WHERE ID in (SELECT ID FROM DELETED WHERE Lock = 3);' +
				' UPDATE [dbo].[' + @TableName + '] SET Lock = 3 WHERE ID in (SELECT ID FROM DELETED);'+
				' END';

			EXECUTE (@Statement) AS LOGIN = 'sa';
			
			SET @Statement =
				' CREATE TRIGGER [dbo].[Update' + @TableName + ']' +
				' ON  [dbo].[' + @TableName + ']' + 
				' AFTER INSERT,UPDATE' +
				' AS' + 
				' BEGIN' +
					' SET NOCOUNT ON;' +
					' UPDATE [dbo].[' + @TableName + '] SET LastChangeOn = GetDate(), LastChangeBy = user_name() WHERE ID in (SELECT ID FROM Inserted);' +
				' END';
			
			EXECUTE (@Statement) AS LOGIN = 'sa';
		
		END TRY
		BEGIN CATCH
		
		END CATCH
	end
END

Ich hätte ja erwartet dass die Statements nur bei Create Ausgeführt werden und dass die Trigger mit den Tabellen Gelöscht werden.
Von all den Sachen, die mir verloren gegangen, hab ich am meisten an meinem Verstand gehangen... MfG...
private Nachricht | Beiträge des Benutzers
Florian Reischl
myCSharp.de - Experte

Avatar #avatar-2880.jpg


Dabei seit:
Beiträge: 1.564
Herkunft: München

beantworten | zitieren | melden

8o 8o

Erstmal was anderes...

DML Trigger beim erzeugen jeder Tabelle automatisch über einen DB-Trigger auf alle Tabellen klatschen und dabei kein Error-Handling??
Gib wenigstens eine Meldung über PRINT aus dass eine - vom wem auch immer - neu erzeugte Tabelle gerade einen Trigger gewonnen hat. Außerdem solltest du die Existenz deiner Spalten korrekt prüfen und den Trigger dann auch nur dann erzeugen wenn die Spalten vorhanden sind, dann kannst du auch ein korrektes Error-Handling einbauen.

Ich würde sowieso von solchen Triggern abraten. Da versteht keiner von außen was passiert. Nimm für sowas Prozeduren und passe die Security-Einstellungen so an dass von außen keiner Daten löschen kann. Mit Prozeduren sind solche Effekte wie du sie hast gar nicht erst möglich und der DBA und alle anderen verstehen was passiert.

Zu deiner Frage...

Der gepostete DB Trigger wird definitiv nur gefeuert wenn du eine Tabelle erzeugst, nicht wenn du eine änderst. Kann es sein, dass du das SSMS verwendest um deine Tabellen anzupassen und dabei Spalten umsortierst oder Datentypen änderst?

Grüße
Flo
Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.
private Nachricht | Beiträge des Benutzers
Atomroflman
myCSharp.de - Member



Dabei seit:
Beiträge: 266
Herkunft: Hamburg

Themenstarter:

beantworten | zitieren | melden

Ja ich habe das benutzt und nen PK hinzugefügt.

Die Spalten sind immer vorhanden, da auch diese automatisch angelegt werden.

Ich habe das Problem auch schon gelöst. Es hing an einem Flag was gesetzt werden muss, damit der Trigger den Fehler nicht schmeisst der gecatcht werden soll...

SET XACT_ABORT OFF;

Den Rest des Codes erspar ich eich mal.

Ziel des ganzen war dass ich an jeder Zeile sehen kann wer / wann zuletzt an daran geändert hat.
Von all den Sachen, die mir verloren gegangen, hab ich am meisten an meinem Verstand gehangen... MfG...
private Nachricht | Beiträge des Benutzers
Florian Reischl
myCSharp.de - Experte

Avatar #avatar-2880.jpg


Dabei seit:
Beiträge: 1.564
Herkunft: München

beantworten | zitieren | melden

Hallo Atomroflman
Zitat von Atomroflman
Ziel des ganzen war dass ich an jeder Zeile sehen kann wer / wann zuletzt an daran geändert hat.
Das Prinzip habe ich erkannt, Trigger haben halt immer den großen Nachteil dass man nicht sieht was passiert. Zum Hinzufügen von User/Zeitstempel Informationen kann man sie schon verargumentieren (wobei ich eine Prozedur trotzdem besser verständlich finde).

Woran ich mich eher aufgehängt habe ist einmal der leere CATCH-Block und dein DELETE Trigger. Mach' doch eine History-Tabelle und schieb' die gelöschten Daten da rein, das ist wesentlich verständlicher.

Grüße
Flo
Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.
private Nachricht | Beiträge des Benutzers
Atomroflman
myCSharp.de - Member



Dabei seit:
Beiträge: 266
Herkunft: Hamburg

Themenstarter:

beantworten | zitieren | melden

Das Programm ist so angelegt dass es beim selektieren alle Zeilen ignoriert die das Lock auf 3 gesetzt haben. Das tut es in jeder Tabelle. Ich habe nur versucht das setzen aus dem Programm in die DB zu verlagern.

Die Locked Zeilen können über einen Schalter wieder angezeigt werden. Wenn der User nun merkt, dass er eine falsche Zeile gelöscht hat kann er sie wieder holen, ausser sie wurde bereits überschrieben.
Von all den Sachen, die mir verloren gegangen, hab ich am meisten an meinem Verstand gehangen... MfG...
private Nachricht | Beiträge des Benutzers