Mehrere Trigger gegen einen einzelnen Trigger

8

Szenario:

Jedes Mal, wenn Daten in / aus einer Tabelle eingefügt / aktualisiert / gelöscht werden, müssen bis zu drei Dinge passieren:

  1. Die Daten müssen in einer separaten Tabelle
  2. protokolliert werden
  3. Referenzielle Integrität muss auf impliziten Daten angewendet werden (ich beziehe mich auf Daten, die mit einer Fremdschlüsselbeziehung verknüpft werden sollten, aber nicht: z. B. wenn eine Aktualisierung Table1.Name auch Table2.Name auf die aktualisieren soll gleicher Wert)
  4. Beliebige Geschäftslogik muss ausgeführt werden

Die Architektur und das Schema der Datenbank dürfen nicht geändert werden, und die Anforderungen müssen mithilfe von Triggern erfüllt werden.

Frage

Welche Option ist besser?:

  1. Ein einzelner Trigger pro Operation (Einfügen / Aktualisieren / Löschen), der mehrere Probleme behandelt (Protokolle, erzwingt implizite referenzielle Integrität und führt beliebige Geschäftslogik aus). Dieser Trigger könnte D_TableName ("D" für delete) heißen.
  2. Mehrere Auslöser pro Vorgang, die nach Belangen getrennt wurden. Sie könnten benannt werden:

    • D_TableName_Logging - für die Protokollierung, wenn etwas aus
    • gelöscht wird
    • D_TableName_RI
    • D_TableName_BL

Ich bevorzuge Option 2, weil eine einzelne Code-Einheit eine einzige Sorge hat. Ich bin kein DBA und kenne mich mit SQL Server aus, um mich gefährlich zu machen.

Gibt es zwingende Gründe, alle Bedenken in einem einzigen Auslöser zu behandeln?

    
Dan 03.01.2013, 19:06
quelle

4 Antworten

4

Wow, Sie befinden sich in einer Situation ohne Gewinn. Wer immer verlangt hat, dass all diese Dinge über Trigger erledigt werden, sollte erschossen und dann abgefeuert werden. Erzwingen RI über Trigger?

Sie haben gesagt, dass die Architektur und das Schema der Datenbank nicht geändert werden dürfen. Durch das Erstellen von Triggern ändern Sie jedoch zumindest das Schema der Datenbank und, argumentieren Sie, die Architektur.

Ich würde wahrscheinlich mit Option # 1 gehen und zusätzliche gespeicherte Prozeduren und UDFs erstellen, die sich um Logging, BL und RI kümmern, so dass Code nicht doppelt vor den einzelnen Triggern (die Trigger würden diese gespeicherten Procs und / oder UDFs aufrufen) . Ich mag es wirklich nicht, die Trigger so zu benennen, wie Sie es in Option 2 vorgeschlagen haben.

Übrigens, bitte sagen Sie jemandem in Ihrer Organisation, dass dies verrückt ist. RI sollte nicht über Trigger erzwungen werden und Geschäftslogik gehört NICHT in die Datenbank.

    
Randy Minder 03.01.2013, 19:11
quelle
2

All dies in einem Trigger zu tun, ist möglicherweise effizienter, da möglicherweise weniger Operationen gegen die (nicht indexierten) Tabellen inserted und deleted durchgeführt werden können.

Auch wenn Sie mehrere Trigger haben, können Sie den ersten und letzten feuern, aber alle anderen feuern in beliebiger Reihenfolge, so dass Sie die Abfolge der Ereignisse nicht deterministisch steuern können, wenn Sie mehr als 3 Trigger für einen bestimmten Trigger haben Aktion.

Wenn keine dieser Überlegungen zutrifft, dann ist es nur eine Frage der Präferenz.

Natürlich ist es selbstverständlich, dass die Spezifikation, um dies mit Triggern zu tun, saugt.

    
Martin Smith 03.01.2013 19:11
quelle
2

Ich stimme @RandyMinder zu. Ich würde jedoch noch einen Schritt weiter gehen. Auslöser sind nicht der richtige Weg, um dieser Situation zu begegnen. Die Logik, die Sie beschreiben, ist zu kompliziert für den Auslösemechanismus.

Sie sollten Einfügungen / Aktualisierungen / Löschungen in gespeicherten Prozeduren umbrechen. Diese gespeicherten Prozeduren können die Geschäftslogik und die Protokollierung usw. verwalten. Außerdem machen sie es offensichtlich, was passiert. Eine Kette gespeicherter Prozeduren, die gespeicherte Prozeduren aufrufen, ist explizit. Eine Kette von Auslösern, die Auslöser aufrufen, wird durch Einfügen / Aktualisieren / Löschen von Anweisungen bestimmt, die den Aufruf des Auslösers nicht explizit machen.

Das Problem mit Triggern ist, dass sie Abhängigkeiten und Sperren zwischen verschiedenen Tabellen einführen, und es kann ein Albtraum sein, die Abhängigkeiten zu entwirren. Ebenso kann es ein Albtraum sein, Leistungsengpässe zu ermitteln, wenn das Problem in einem Auslöser liegt, der einen Auslöser aufruft, der eine gespeicherte Prozedur aufruft, die einen Auslöser aufruft.

    
Gordon Linoff 03.01.2013 19:17
quelle
0

Wenn Sie Microsoft SQL Server verwenden und den Code zum Ausführen der DML-Anweisungen ändern können, können Sie das OUTPUT-Klausel , um die aktualisierten, eingefügten, gelöschten Werte in temporäre Tabellen oder Speichervariablen anstelle von Triggern auszugeben. Dies wird die Leistungseinbußen auf ein Minimum beschränken.

    
Tristan Barcelon 10.03.2016 01:57
quelle