none
Trigger und Auslöser (User) RRS feed

  • 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

    Donnerstag, 7. Juni 2012 09:51

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.

    Grüße

    Oliver


    Donnerstag, 7. Juni 2012 09:56
  • 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

    Donnerstag, 7. Juni 2012 10:11
  • 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

    Donnerstag, 7. Juni 2012 10:31
    Moderator
  • 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

    Donnerstag, 7. Juni 2012 10:46
  • 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

    Donnerstag, 7. Juni 2012 11:48
  • 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

    Donnerstag, 7. Juni 2012 12:03
    Moderator