Fragensteller
Trigger und Auslöser (User)

Frage
-
Hallo,
ich habe ein ASP.NET Projekt, in welchem über die Form-Autentifizierung sich die User anmelden. Nun möchte ich gerne jede Änderung in der Datenbank (MS SQL Express) über Trigger speichern mit der Information, welcher User die Änderung durchgeführt hat und wann.
Ist das möglich mit Triggern? ich habe für das Ändern und Löschen mal folgendes getestet, was auch funktioniert - jedoch weiß ich noch nicht, wie ich die Information zu dem User mit in die neue Tabelle bekomme:
ALTER TRIGGER [dbo].[DelSO] on [dbo].[schedulerobject] for delete, update as insert into schedulerdeleteobject select sid, startdatetime, enddatetime,objectart,obejecttext from deleted
Gibt es dort Möglichkeiten, die entsprechenden User und die Zeit mit zu speichern?
LG
Claudia
Alle Antworten
-
Hi,
greifst du mit deinem ASP.NET Projekt mit einem zentralen Benutzer auf die Datenbank zu oder authentifiziert sich der Benutzer direkt an der DB.
Im zweiten Fall, kannst du die über den Aufruf "USER" den aktuell an der DB angemeldeten Benutzer ermitteln.
Die aktuelle Zeit, kannst du mit GetDate() ermitteln.
- Bearbeitet Oliver Rzeniecki Donnerstag, 7. Juni 2012 09:57
-
Hallo Oliver,
ich greife auf die Datenbank mit einem zentralen Benutzer zu, welcher in der Datenbank festgelegt wurde. In der web.config habe ich meinen ConnectionString definiert:
<connectionStrings> <add name="DBConnectionString" connectionString="Data Source=LAB\SQLEXPRESS;Initial Catalog=testdb;User Id=projekt;Password=pwd;" providerName="System.Data.SqlClient"/> </connectionStrings>
Das wird wohl das Problem werden, oder?
Claudia
-
Hallo Claudia,
wenn Du es richtig machen willst, bleibt dir eigentlich nicht viel anderes übrig, als eben mit einzelnen SQL Benutzern für die Anwendungsbenutzer zu arbeiten. Dann kannst Du den Benutzernamen über
SELECT SUSER_SNAME()
ermitteln. Nur mittels SELECT USER erhältst Du je nach Benutzeraccount nicht den korrekten Benutzernamen, sondern bspw. "dbo", ...
Als (nicht wirklich zu empfehlende und ggfs. auch nicht 100%ig funktionierende) Alternative könntest Du:
a) Den Benutzernamen vorher in eine temporäre Tabelle schreiben und diesen dann dort nochmal auslesen
b) Eine SP erstellen, die das Löschen bzw. das Aktualisieren vornimmt. Dort kannst Du dann auch den Benutzernamen übergeben
c) Eine Art "Lösch-/Aktualisierungstabelle" erstellen. Das sieht dann bspw. so aus:
TableName PrimaryKey Action UserName Daten 1 UPDATE BenutzerA Daten 2 DELETE BenutzerA ...
Du würdest also vorher die Aktionen des jeweiligen Datensatzes zusammen mit dem Benutzernamen speichern und diese dann im Trigger auslesen.
Zwei der vielen Probleme hierbei sind dann konkurrierende Aktionen, Sperren, ...
Wie gesagt, empfehlenswert ist eigentlich nur die Variante, mit einzelnen Benutzern auf der Datenbank zu arbeiten.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Hallo Claudia,
Ich hatte vor einiger Zeit mal eine Diskussion über das gleiche Szenario, vielleicht wäre das bei Dir auch praktikabel: http://social.msdn.microsoft.com/Forums/de-de/sqlexpress/thread/565762e0-dada-470f-88ca-234fd9c9ffa3
Da wird mit Context_Info gearbeitet, um festzulegen, welcher "anonyme" User gerade eine Aktion ausführt.
Olaf Helper
* cogito ergo sum * errare humanum est * quote erat demonstrandum *
Wenn ich denke, ist das ein Fehler und das beweise ich täglich
Blog Xing -
Hallo,
Danke erst einmal für die Tipps. Ich habe noch nicht angefangen mit der Userverwaltung. Noch kann ich mich entscheiden.
Folgende Idee habe ich, weiß aber nicht ob ich sie umsetzen kann. Ich lege beim Anlegen der Form Autentifizierung Benutzer und Passwort fest, welches dann auch über eine Gespeicherte Prozedur einen DB User als db_owner anlegt.
Kann das funktionieren (wie???)? Wie kann ich aber dann auf meinem ConnectionString zugreifen mit den Benutzerdaten? Die Seiten mit den ObjectDataSource und SqlDataSource sind soweit fertig und beziehen sich alle auf den genannten ConnectionString.
Ich würde mich über ein paar Tipps, wie ihr es machen würdet, freuen.
LG
Claudia
-
Hallo Claudia,
zuerst das wichtige: Lass bloß SqlDataSource weg. Damit machst Du dir nur Probleme, die Du nicht haben willst.
Jeden User als dbo anzulegen, halte ich nicht für sinnvoll. Dann lieber die Rollen db_datareader und ggfs. db_datawriter zuweisen.
Den Benutzer anlegen kannst Du bspw. mit folgendem SQL Skript.
/* Template script for user management */ USE [master] IF EXISTS ( SELECT * FROM sys.server_principals WHERE name = N'{UserName}' ) BEGIN ALTER LOGIN [{UserName}] WITH PASSWORD = N'{Password}' END IF NOT EXISTS ( SELECT * FROM sys.server_principals WHERE name = N'{UserName}' ) BEGIN CREATE LOGIN [{UserName}] WITH PASSWORD = N'{Password}', DEFAULT_DATABASE = [{Database}], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF END USE [{Database}] IF NOT EXISTS ( SELECT * FROM sys.database_principals WHERE name = N'{UserName}' ) BEGIN CREATE USER [{UserName}] FOR LOGIN [{UserName}] WITH DEFAULT_SCHEMA=[dbo] EXEC sp_addrolemember N'db_datareader', N'{UserName}' EXEC sp_addrolemember N'db_datawriter', N'{UserName}' END
Die einzelnen Platzhalter {UserName}, {Database} und {Password} musst Du natürlich noch mit den richtigen Werten ersetzen. Um ein solches Statement ausführen zu dürfen, benötigst Du aber mehr Rechte, daher solltest Du das ggfs. mit einer separaten Datenbankverbindung mit eigenem Benutzeraccount machen.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community