Wie kann ich einen INSTEAD OF INSERT-Trigger schreiben, der eine Spalte für eine Tabelle setzt?

8

Ich arbeite an einer Legacy-App, die zur Ausführung in einer Multi-Tenant-Konfiguration erweitert wird. Die Basisarchitektur übernimmt die alte Anwendung und fügt jeder Tabelle eine StoreID -Spalte hinzu. Jeder Tenant sieht dann die Legacy-Tabellen über eine Reihe von Ansichten, die nach der Store-ID filtern, etwa wie folgt:

%Vor%

Es ist ein bisschen schicker als das, aber das vereinfacht die Frage.

Jetzt kann ich einen Trigger wie diesen erstellen

%Vor%

Annahme einer einfachen Tabelle mit Spalten Name und StoreId.

Mein Problem ist, dass ich über 100 Tabellen habe und wenn ich diesem Muster folgen würde, müsste ich einen speziellen Trigger für jede Tabelle machen, der alle Felder für jeden von ihnen auflistet. Nicht nur, dass es auf kurze Sicht lästig ist, ist ein Wartungs-Albtraum, da jede Tabellenänderung Trigger-Modifikationen enthalten müsste.

Also, wie könnte man einen Trigger schreiben, der nur bei jedem Einfügen oder Update sagt, das StoreId-Feld für jede Tabelle mit einer StoreId auf 99 setzen?

Danke, dass Sie einem SQL-Neuling geholfen haben!

    
Ukko 08.09.2010, 20:52
quelle

4 Antworten

7

So scheint es, dass Sie mehrere Schemas verwenden, um die Geschäftsinformationen zu übermitteln, während Objektnamen konsistent bleiben, mit einem Schema pro Geschäft, ja? Und eine Art Verbindung / Benutzermagie, damit Abfragen die richtigen Ansichten treffen.

Wenn ja, präsentiere ich zwei ungeheuerliche Hacks und eine empfohlene Lösung (damit Sie Ihre Optionen kennen).

Egregious hack # 1 nimmt an, dass die Geschäftsansichten alle Spalten aus der Basistabelle außer StoreId in der gleichen Ordnungszahl wie die Basistabelle und keine anderen Spalten enthalten :

%Vor%

Wenn Sie der Basistabelle jemals eine Spalte hinzufügen, müssen Sie alle Geschäftsansichten aktualisieren, um die Spalte einzuschließen, oder die Trigger werden unterbrochen.

Egregious hack # 2 nimmt dasselbe wie (1) an, außer dass StoreId in den Geschäftsansichten enthalten ist:

%Vor%

Der Vorteil von hack # 2 gegenüber hack # 1 ist, dass Sie Ihre Geschäftsansichten mit SELECT * definieren können. Wenn sich die Basistabellen ändern, kompilieren Sie einfach alle Geschäftsansichten mit sp_refreshview . Der Nachteil ist, dass Sie eingefügte Daten von einer Zwischentabelle in eine andere kopieren und die zweite Tabelle aktualisieren. Dies hat den Overhead Ihres INSTEAD OF INSERT -Auslösers verdreifacht, der zu Beginn bereits ziemlich teuer war. dh

  • Basis-Overhead von INSTEAD OF INSERT trigger - & gt; Kosten zum Auffüllen inserted - & gt; %Code%.
  • Kosten zum Auffüllen von x von #inserted - & gt; etwa inserted .
  • Kosten zum Aktualisieren von x - & gt; über #inserted
  • Gesamtaufwand für ungeheuerlichen Hack # 2: ca. 3 x

Also sonst ist es das Beste, die Trigger auszulösen. Es ist ein ziemlich unkomplizierter Prozess, sobald Sie mit den Systemtabellen vertraut sind, und Sie können die Triggergenerierung optimieren, wie Sie es für richtig halten. In diesem Fall sollten Sie auch die Geschäftsansichten scripten.

Um Sie zu starten:

%Vor%     
Peter Radocchia 09.09.2010, 02:25
quelle
2

Also, wenn ich richtig verstanden habe, hat jeder Laden seine eigene ID. Die DB wird in jedem Geschäft bereitgestellt, und die DB sollte eine andere StoreId basierend auf dem Ort, an dem sie implementiert wurde, mit minimalem Codeaufwand aufzeichnen. Hier ist, was ich vorschlage. Erstellen Sie eine Tabelle in der Datenbank, um die StoreId zu speichern. Erstellen Sie eine Funktion, um diese StoreId abzurufen. Erstellen Sie dann die StoreId-Spalte in jeder Tabelle als eine berechnete Spalte, die die Funktion verwendet. Bei jeder Bereitstellung besteht die einzige Änderung darin, die StoreId in einer Tabelle zu aktualisieren. Etwas wie:

%Vor%     
Joe Stefanelli 08.09.2010 21:26
quelle
2

Anstatt Trigger zu verwenden, sollten Sie nicht jede Tabelle aktualisieren, indem Sie StoreId NOT NULL setzen und ihr einen Standardwert von 99 geben?

Bearbeiten basierend auf Klarstellungen

Sie könnten einen AFTER INSERT, UPDATE-Trigger als Alternative zu einem INSTEAD OF-Trigger versuchen

%Vor%

Während dies die gerade eingefügten oder aktualisierten Daten aktualisiert, hat es den Vorteil, dass es nicht bricht, wenn Sie Spalten aus den Tabellen hinzufügen oder daraus entfernen.

    
LittleBobbyTables 08.09.2010 20:56
quelle
0

Ich bin gerade über diese alte Frage gestolpert:

Sie können eine Standardeinschränkung für die StoreId erstellen (alle Tabellen mit der Spalte StoreId finden, indem Sie sys.columns auswählen), entweder für eine feste 99 oder eine Funktion, die eine Suche in einer anderen Tabelle durchführt oder eine Funktion, die eine feste 99 zurückgibt (so dass Sie nur eine Funktion anstelle von 100 Einschränkungen ändern müssen, wenn Sie die Datenbank in einen anderen Speicher verschieben)

    
Thomas Franz 07.12.2015 14:07
quelle

Tags und Links