Announcement

Collapse
No announcement yet.

Datensatzänderungen protokollieren

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Datensatzänderungen protokollieren

    Hallo Forum,

    bin in Sachen VB ein noch ziemlich unbeschriebenes Blatt! Ich brauche Hilfe, Beispiele oder Anregungen!

    Ich soll ein bestehende und gut funktionierende Access-Anwendung nach VB.NET portieren! Warum auch immer! Habe es auch größtenteils alles in VB umsetzen können!

    Vorab: Ich nutze VB 2005 Express!

    Nun das Problem: Habe eine SQL-ServerDatenquelle hinzugefügt, und die Attribute auf einem Form! Das funktioniert so weit ganz gut! Was ich nicht hinkriege ist: Wenn ein Datensatz geändert wird, soll zeitgleich mit der Aktualisierung des Datensatzes in eine andere Tabelle geschrieben werden, welches Feld, alte Wert, neue Wert, wann und wer die Änderung vorgenommen hat.

    In Access gibt es die beiden Eigenschaften AfterUpdate und BeforeUpdate, die ich allerdings in VB vermisse!

    Hätte vielleicht jemand ne Idee wie sowas umzusetzen ist?

    Vielen Dank vorab!
    Mfg
    Eddie

  • #2
    Hallo,

    wenn eine SQL Server-Datenbank verwendet wird, kann dort direkt im SQL Server ein so genannter Trigger die Änderungen in der zweiten Tabellen protokollieren. Im VB-Anwendungsprogramm sind kann keine Vorkehrungen notwendig.

    Das folgende Beispiel legt im MS SQL Server zwei Tabellen mit einem derartigen Trigger an. Die Logtabelle TestTblAudit stellt dazu die Spalten oldval und newval zur Verfügung. Damit dort alle zulässigen SQL-Datentypen abgelegt werden können, werden beide Spalten mit dem Datentyp SQL_VARIANT angelegt. Der Trigger kann somit zur CAST-Funktion greifen, um die jeweiligen Werte aus Inserted und Deleted als Variant abzurufen. Der Protokollierungseintrag wird nur dann in die Logtabelle hinzugefügt, wenn sich der neue Wert vom alten Wert unterscheidet.

    Code:
    USE tempdb
    GO
    
    IF OBJECT_ID('dbo.TestTbl') IS NOT NULL
      DROP TABLE dbo.TestTbl;
    GO
    
    IF OBJECT_ID('dbo.TestTblAudit') IS NOT NULL
      DROP TABLE dbo.TestTblAudit;
    GO
     
    CREATE TABLE dbo.TestTbl
    (
      testtbl_id INT         NOT NULL IDENTITY PRIMARY KEY,
      intcol    INT         NULL,
      varcharcol VARCHAR(10) NULL
    )
    GO
    
    CREATE TABLE dbo.TestTblAudit
    (
      lsn        INT         NOT NULL IDENTITY PRIMARY KEY,
      testtbl_id  INT         NOT NULL,
      colname     SYSNAME     NOT NULL,
      oldval      SQL_VARIANT NULL,
      newval      SQL_VARIANT NULL
    )
    GO
    
    
    CREATE TRIGGER trTestTblUpdateAudit 
      ON dbo.TestTbl 
      FOR UPDATE
    AS
      -- Gibt es etwas zu tun?
      IF @@rowcount = 0 
        RETURN;
      -- Datensatzänderung in der Tabelle TestTblAudit speichern
      INSERT INTO dbo.TestTblAudit(testtbl_id, colname, oldval, newval)
        SELECT *
        FROM (SELECT I.testtbl_id, colname,
              CASE colname
                WHEN N'intcol' THEN CAST(D.intcol AS SQL_VARIANT)
                WHEN N'varcharcol' THEN CAST(D.varcharcol AS SQL_VARIANT)
              END AS oldval,
              CASE colname
                WHEN N'intcol' THEN CAST(I.intcol AS SQL_VARIANT)
                WHEN N'varcharcol' THEN CAST(I.varcharcol AS SQL_VARIANT)
              END AS newval
            FROM inserted AS I
              JOIN deleted AS D
                ON I.testtbl_id = D.testtbl_id
              CROSS JOIN
                (SELECT N'intcol' AS colname
                UNION ALL SELECT N'varcharcol') AS C) AS D
      WHERE oldval <> newval
        OR oldval IS NULL AND newval IS NOT NULL
        OR oldval IS NOT NULL AND newval IS NULL;
    GO
    
    -- Testdatensätze anlegen
    INSERT INTO dbo.TestTbl(intcol, varcharcol) VALUES(10, 'A');
    INSERT INTO dbo.TestTbl(intcol, varcharcol) VALUES(20, 'B');
    INSERT INTO dbo.TestTbl(intcol, varcharcol) VALUES(30, 'C');
    
    GO
    -- das Verhalten des Triggers testen 
    UPDATE dbo.TestTbl
      SET varcharcol = varcharcol + 'X',
          intcol = 40 - intcol
    WHERE testtbl_id < 3;
    
    -- Das Ergebnis vergleichen
    SELECT * FROM dbo.TestTbl;
    SELECT * FROM dbo.TestTblAudit;
    GO
    Der Trigger kann über die MS SQL Server-Funktion CURRENT_USER auch den Benutzernamen auslesen, der den Datensatz der 1. Tabellen ändert.
    Zuletzt editiert von Andreas Kosch; 24.07.2007, 07:41.

    Comment


    • #3
      Vielen Dank!

      Das ist natürlich richtig! Hab ich nicht dran gedacht!

      Jetzt aber nur interesse halber! Wie ist denn vorzugehen wenn statt dem SQL-Server eine Access-Datenbank genommen wird??? Da hab ich keine Trigger!

      Gruß
      Eddie

      Comment

      Working...
      X