Hintergrundinformation:
- Ich erstelle eine Sammlung von Überwachungstabellen, um Aktualisierungen zu verfolgen und eine Reihe von Datentabellen für meine App zu löschen.
- Audit-Datensätze werden über Trigger erstellt.
- DML in der Datenbank meiner App stammt im Allgemeinen aus einem Login, mit dem ein Dienst in die Datenbank gelangt. Aus diesem Grund denke ich, dass das Ergebnis von
SYSTEM_USER
immer das gleiche sein wird, wenn ein Trigger aufgerufen wird. - Meine App speichert derzeit keine Benutzerdaten, obwohl
UserId
ihr jedes Mal eine Zeichenfolge zugewiesen wird , wenn DML ausgeführt werden soll (ausschließlich in gespeicherten Prozeduren).
Das Problem, auf das ich gestoßen bin, ist, dass ich wissen möchte, wer es getan hat, wenn ein Benutzer einen Datensatz löscht. Da dies durch dieselbe Anmeldung erfolgt, möchte ich nicht sehen, dass alle Aktionen vom Dienst ausgeführt wurden. Ich möchte sehen, welcher Benutzer dies getan hat. Dies ist kein Problem bei einem Update, da wir ModifiedBy
Spalten haben, die über eine bei UserId
Updates gesendete Datei aktualisiert werden.
Die Frage ist: Gibt es eine Möglichkeit SYSTEM_USER
, die Benutzerinformationen festzulegen oder auf andere Weise in den Trigger zu bekommen, wenn ein Löschvorgang ausgeführt wird?
Die "beste" Idee, die ich derzeit habe, obwohl ich noch nicht sicher bin, ob es eine gute Idee ist, ist, dass ich im Dienst überprüfe, ob sich der aktuelle UserId
als Benutzer in der Datenbank befindet, und wenn nicht, einen Benutzer zu erstellen Objekt für sie. Führen Sie dann gespeicherte Prozeduren mit aus EXECUTE AS User = @UserId
. Wenn dann DML in der gespeicherten Prozedur ausgeführt wird und der Trigger ausgelöst wird, SYSTEM_USER
sollte der Benutzer von der zurückgegeben werden EXECUTE AS
.
quelle
Antworten:
Während die Verwendung
EXECUTE AS User = @UserId
möglicherweise die beste Option ist (abhängig von anderen Problemen), gibt es hier einen alternativen Ansatz:Führen Sie in Ihren gespeicherten Prozeduren oder jederzeit in Ihrer SQL-Sitzung
DELETE
den folgenden Befehl aus, bevor Sie den folgenden Befehl ausführen:Dann können Sie in Ihrem Trigger diesen Wert mit abrufen
Dies hat einige Nachteile, von denen der wichtigste darin besteht, dass Sie CONTEXT_INFO nicht ohne weiteres für mehrere Dinge gleichzeitig verwenden können.
quelle
Abhängig davon, wie Sie den Benutzerkontext von der individuellen Anmeldung zur Dienstanmeldung ändern, ist ORIGINAL_LOGIN () möglicherweise hilfreich.
http://technet.microsoft.com/en-us/library/ms189492.aspx
"Diese Funktion kann beim Überprüfen der Identität des ursprünglichen Verbindungskontexts hilfreich sein. Während Funktionen wie SESSION_USER und CURRENT_USER den aktuell ausgeführten Kontext zurückgeben, gibt ORIGINAL_LOGIN die Identität des Logins zurück, der in dieser Sitzung zuerst mit der Instanz von SQL Server verbunden war."
quelle
Sie können auch versuchen
Host_Name
, Ihre Tabellen zu ergänzen. Ich habe festgestellt, dass ich in Situationen, in denen ich ein gemeinsames Login habe, eine Person normalerweise anhand ihres Computernamens aufspüren kann, da 95% der Zeit eine Person von ihrem eigenen Computer aus arbeitet. Es funktioniert nicht immer, aber es kann eine nützliche sekundäre Information sein.Leider funktioniert dies nicht, wenn Sie mit einer Webanwendung arbeiten, bei der der Host immer die Webanwendung selbst sein wird, aber es könnte sich lohnen, es zu versuchen.
quelle