Gestern las ich bei coreworxx den Artikel "UPDATE Trigger – schon mal reingefallen?" und wollte auch gleich einen Kommentar schreiben. Weil ich dazu aber einen Google-Account einrichten müsste, antworte ich lieber hier und setze einen Trackback…
Schade, weil ich jetzt erst mal den Kontext herstellen muss, damit man nicht erst den einen Artikel lesen muss, um diesen zu verstehen. Übrigens liebe ich es Artikel über SQL-Themen zu lesen: also bitte nicht abschrecken lassen…
Andreas Gümbel beschreibt in dem Artikel, wie man mittels der Tabellen INSERTED und DELETED mitbekommt wie die Werte des geänderten Datensatzes vor und nach der Änderung kommt. Hier eines seiner Beispiele:
CREATE TRIGGER [TRIGGER_NAME_Update] ON [dbo].[myTableName]
FOR UPDATE
AS
DECLARE @myInsertId int
SELECT @myInsertId=myTableId FROM INSERTED
[weitere Verarbeitung …]
Das ist völlig korrekt beschrieben.
Aber dennoch würde ich von diesem Statement abraten. Es geht strikt davon aus, dann immer nur ein einziger Datensatz geändert wird. Um die optimale Performance zu erreichen werden in Datenbanksystemen aber immer möglichst alle betroffenen Datensätze mit einem Schwupps geändert.
Ich merke immer wieder, dass es gerade altgedienten Programmierern schwer fällt, dass man jetzt nicht mehr mühsam alles über eine Schleife machen muss: In SQL macht man das mit einem einzigen Befehl. Hier mein Lieblingsbeispiel: Alle Mitarbeiter der Datenbankbetreuung bekommen eine 10%ige Gehaltserhöhung…
UPDATE Stammdaten.Mitarbeiter
SET Gehalt = Gehalt * 0.1
WHERE team='Datenbanktechnologie'
Das Statement dauert fast genau so lange wie der Update eines einzelnen Datensatzes. Deswegen macht man eher selten einen Update auf einen Satz. Und selbst wenn man jetzt fest überzeugt ist, dass man niemals mehrere Sätze gleichzeitig wird. Sollte man das dennoch vorsehen, weil sich meiner Erfahrung nach sehr schnell die Randbedingungen ändern und "Puff" knallt der Trigger mitten im laufenden Betrieb an die Wand.
Das ist übrigens eine Tuningmaßnahme, die ich immer wieder bei Performanceanalysen empfehlen muss: Mengenupdates anstelle von Schleifen. In der ersten Runde geht es meist auf gar keinen Fall, weil man ja in dem jeweiligen Objekt keine Infos darüber hat, welche anderen Objekte sonst noch betroffen sind. Wenn der Druck von Seiten der Kunden steigt, geht es meistens doch…
Daher: Im Trigger selber bitte immer die Verarbeitung von mehreren Datensätzen vorsehen.
OK, die 10% Gehaltserhöhung habe ich mir nicht verdient 😉
Eigentlich wollte ich ja lediglich auf die Problematik des Updates hinweisen. Ich werde dem Blogbeitrag deine Anmerkungen hinmzufügen, wenn nichts dagegen spricht …
Hab ich noch vergessen:
Natürlich versuche ich als "algedienter" 😉 Programmierer ebenfalls die Datenbank ihren Job machen zu lassen und eben nicht einzelne SQL-Statements über eine Schleife o.ä. gegen die Datenbank fahren zu lassen. Das Beispiel sollte lediglich die Problematik des Update-Triggers veranschaulichen.
Mit dem "altgedienten Programmierern" wollte ich zum Ausdruck bringen, dass ich der angesprochenen Problematik immer wieder begegne. Das ist auch die Begründung, warum ich so auf diesen Aspekt in Deinem Posting abgesprungen bin. Und das obwohl ich schon merkte, dass es Dir um den Aspekt der virtuellen Tabellen INSERTED und DELETED geht.
Lass Dich nicht vergrätzen. Ich lese unheimlich gerne SQL-Artikel und fachsimpel darüber. Also: Weiter so!
Und natürlich spricht nichts dagegen Deinen Artikel um diesen Aspekt zu ergänzen.
Hi Thomas, keine Angst, ich lass mich nicht vergrätzen 🙂
Einer Problematik bin ich mir aber durchaus auch bewußt, und zwar dass ein Programmierer nicht automatisch auch ein Datenbankspezialist sein muss (und umgekehrt). Ich denke dieser Umstand führt leider oft genug zu, ich nenne es mal "ungünstigen" Lösungen – egal ob es dabei die Performance, Stabilität oder andere Aspekte einer Lösung betrifft.
Wie auch immmer, deinen Blog habe ich jedenfalls "gebookmarked" …
Gruß
Andi