2016-05-16 6 views
0

Ich habe zwei SQL Server-Datenbanken.Verwenden von Triggern, um die Datenintegrität von ähnlichen Tabellen in zwei Datenbanken zu erhalten

Eines wird als Back-End für ein Ruby-On-Rails-System verwendet, von dem wir aufgrund der Ruby-Anwendungen, die wir in ASP.NET MVC umschreiben, noch verwendet werden.

Die Datenbanken haben ähnliche Tabellen, aber nicht identisch für die Tabellen Benutzer, Rollen und Rollen-Benutzer.

Ich möchte eine Art von Trigger erstellen, um die Tabellen user und roles-users auf jeder Datenbank zu aktualisieren, wenn eine Änderung an der anderen Datenbank der gleichen Tabelle vorgenommen wird.

Ich kann nicht einfach die Benutzer-Tabelle in der ursprünglichen Datenbank verwenden, weil Ruby eine andere Hash-Funktion für die Kennwörter hat, aber ich möchte sicherstellen, dass Änderungen auf dem einen System auf dem anderen sofort wiedergegeben werden. Ich möchte auch das offensichtliche Problem vermeiden, dass ein Update auf der einen Datenbank ein Update auf der anderen Datenbank auslöst, das ein Update auf der ersten auslöst und der Prozess sich selbst wiederholt, bis der Server abstürzt oder etwas Ähnliches passiert oder ein Deadlock auftritt .

Ich möchte keine Datenbankreplikation verwenden.

Gibt es eine etwas einfache Möglichkeit, dies auf einer Transaktion pro Transaktion zu tun?

EDIT

Der Auslöser wäre so etwas wie dies vom Konzept her sein:

USE Original; 
GO 

CREATE TRIGGER dbo.user_update 
ON dbo.user WITH EXECUTE AS [cross table user identity] 
AFTER UPDATE 
AS 
BEGIN 
    UPDATE Another.dbo.users SET column1=value1, etc., WHERE inserted.ID = Another.dbo.users.ID; 
END 

Das Problem, das ich ein rekursive Aufruf zu vermeiden versuchen.

Another.dbo.users wird einen ähnlichen Trigger haben, da die beiden Datenbanken verschiedene Arten von Anwendungen haben, Ruby-On-Rails auf der einen und ASP.NET MVC auf der anderen Seite, die möglicherweise an Daten arbeiten das sollte in den beiden Datenbanken gleich sein.

+0

Haben Sie SQL Trigger gegoogled? Auf welche spezifischen Probleme sind Sie gestoßen, als Sie mit dem Schreiben des Codes begonnen haben und festgestellt haben, dass das nicht funktioniert hat? Wir schätzen es sehr, dass Sie die Anforderungen festgelegt haben, aber haben Sie schon etwas getan? Wenn ja, bitte Code angeben und speziell, was nicht funktioniert hat. – dfundako

+0

Ich habe eine "execute as" -Klausel für die im dml-Trigger eingebettete Anweisung zum Einfügen, Löschen oder Aktualisieren verwendet, um den Vorgang in der anderen Datenbank auszuführen und dann zu überprüfen, ob der Benutzer, der dml ausführt, der datenbankübergreifende Benutzer ist Das cross-database update wird nicht aufgerufen, wenn der Benutzer angibt, dass die andere Datenbank der Ursprung des Aufrufs ist. –

+0

Kühl. Geben Sie den Code an, den Sie ausprobiert haben und der in Ihrem ursprünglichen Post nicht funktioniert. Dann sagen Sie uns, warum es Ihre Anforderungen nicht speziell erfüllt hat. – dfundako

Antwort

0

Ich würde ein Feld zu beiden Tabellen wenn möglich hinzufügen. Beim Hinzufügen oder Aktualisieren einer Tabelle würde das Feld "check" auf 0 gesetzt. Der Trigger würde dieses Feld betrachten und wenn es 0 ist, nachdem es von einem Anwendungsereignis generiert wurde, löst der Trigger das Einfügen/Aktualisieren in die zweite Tabelle aus aber das Prüffeld würde eine 1 anstelle von 0 haben.

Also wenn der Auslöser auf der zweiten Tabelle feuert, wird es den Einsatz zurück in Tabelle eins überspringen.

Dies löst das rekursive Problem.

Wenn Sie aus irgendeinem Grund das Prüffeld nicht hinzufügen können, können Sie eine separate Tabelle mit dem Primärschlüssel für die Tabelle und das Prüffeld verwenden. Dies benötigt mehr Codierung, würde aber auch funktionieren.

+0

Der Zwischentisch klingt wie eine gute Option. Ich kann direkt darauf schreiben und den Auslöser verwenden, um in die zweite Datenbank zu schreiben. Ich glaube nicht, dass die erste Tabelle geändert werden kann, um Felder hinzuzufügen, weil wir viel des Ruby-Codes nicht neu kompilieren können, weil es eine "Legacy" -Version ist und der aktuelle Compiler nicht daran arbeiten wird. –

+0

Es wäre schön, wenn jemand wüsste, wie man auf den Legacy-Ruby-Code zugreifen kann, der Passwort-Hashes aus ASP.NET schreibt. So konnte ich einfach das übergebene Passwort über den Ruby-Hasher ausführen, um den Inhalt der alten Datenbank zu überprüfen). Bis jetzt habe ich keine brauchbare Lösung für dieses Problem gesehen. –

+0

Das wäre meine erste Option persönlich gewesen. Graben Sie in den Legacy-Code, damit ich das reproduzieren kann, bis das System ausfällt. Ich würde eine Update-fähige Ansicht in der neuen DB erstellen, die direkt auf die Legacy-DB-Tabelle verweist. Auf diese Weise bleibt nur ein tatsächlicher Datensatz bestehen und die neuen Anwendungen können mit einem völlig neuen Modell erstellt werden. Neue Felder befinden sich in einer Stub-Tabelle in der neuen DB. Dann, wenn das Legacy bereit ist, in den Ruhestand zu gehen, würde ich die Stub-Tabelle des neuen Systems ändern, um die vollständige Struktur minus Legacy-Felder zu haben, die nicht länger benötigt werden, und die Daten von der Legacy-Tabelle zu portieren –

Verwandte Themen