AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Serverseitiges Logbuch über Datenänderungen
Thema durchsuchen
Ansicht
Themen-Optionen

Serverseitiges Logbuch über Datenänderungen

Ein Thema von ZOD · begonnen am 20. Okt 2017 · letzter Beitrag vom 26. Okt 2017
Antwort Antwort
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#1

AW: Serverseitiges Logbuch über Datenänderungen

  Alt 20. Okt 2017, 09:51
Mir fallen dazu 2,5 Dinge ein:
1. Gerade Firebird handhabt die Updates doch mit neuen Recordversionen. Ich kenne diesen Mechnismus überhaupt nicht, aber es scheint mir naheliegend, sich das vielleicht nutzebar zu machen.. ?
(Einschränkung: Es wäre ein Verfahren, das sehr Produktnahe ist, mit den üblichen Haken.)
2. Gar keine Updates machen, sondern nur inserts und aktive Flag, also quasi eine Highlevel Variante von Firebirds log Mechnismus.
(Einschränkung: Auf Anhieb nicht unbedingt filigran)
2,5. Postgres erlaubt zentrale Trigger, die man prima zum Logging nutzen kann.
Gruß, Jo
  Mit Zitat antworten Zitat
Benutzerbild von joachimd
joachimd

Registriert seit: 17. Feb 2005
Ort: Weitingen
685 Beiträge
 
Delphi 12 Athens
 
#2

AW: Serverseitiges Logbuch über Datenänderungen

  Alt 20. Okt 2017, 10:08
ist http://www.upscene.com/database_audi...and_interbase/ eigentlich noch aktiv? Ist doch genau, was Du willst.
Joachim Dürr
Joachim Dürr Softwareengineering
http://www.jd-engineering.de
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
698 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Serverseitiges Logbuch über Datenänderungen

  Alt 21. Okt 2017, 16:35
In Firebird gibt es keinen zentralen trigger, glaube ich.
im Trigger der tabelle hast du im Insert/update zugriff auf die NEW-Variable, im Update/delete auf die OLD-variable
technisch kannst du dann deine steuertabelle auslesen und dann entsprechend die old/new variableninhalte vergleichen (beim update).
beim insert würde ich keine feld-log schreiben, weil die werte sind ja eh in der tabelle. beim delete musst halt ma schaun, ob du wegspeichern willst, was gelöscht wurde.

Ich selbst mache es nicht in der datenbank, ich habe mir ein Objekt in Delphi geschrieben, welches beim Dokument erstellen sich eine liste der ausgangswerte im Dataset macht und diese in einer stringliste (hab ich vor Jahren geschrieben, jetzt ginge da vllt auch was anderes, denk da an JSON) und diese liste dann komprimiert in die BD.
Beim Editieren dann wurde die alte Liste wieder geladen und beim erneuten Speichern gegen die alte verglichen und gleiche werte rausgeworfen. Geblieben sind nur die veránderten werte und die wurden wieder komprimiert weggeschrieben.
Das ganze waren dann pro formular und zu überwachender tabelle 3 zeilen, das kann man aber noch optimieren mit einem Wrapper der sich um mehrere tabellen kümmert
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
698 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Serverseitiges Logbuch über Datenänderungen

  Alt 21. Okt 2017, 16:36
Da fällt mir ein : dadurch dass du ja eine steuertabelle hast, kannst du naturlich dir den trigger code zusammenbauen on-the-fly wenn man die steuertabelle speichert und dann den trigger schreiben, also programmtechnisch schreiben und als script in die DB setzen.

ich habe das mal schnell geschrieben, musst man eventuell anpassen, habe UniDAC und EhLib genutzt und keine Komfort-Sachen reingeschrieben, also alles fest gecoded :

Code:
unit frmMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, DBGridEhGrouping, ToolCtrlsEh,
  DBGridEhToolCtrls, DynVarsEh, EhLibVCL, GridsEh, DBAxisGridsEh, DBGridEh,
  Vcl.StdCtrls, Vcl.ExtCtrls, UniProvider, InterBaseUniProvider, DBAccess, Uni, Data.DB, MemDS;

type
  TForm5 = class(TForm)
    UniConnection1: TUniConnection;
    UniTransaction1: TUniTransaction;
    InterBaseUniProvider1: TInterBaseUniProvider;
    Panel1: TPanel;
    ComboBox1: TComboBox;
    DBGridEh1: TDBGridEh;
    umdTables: TUniMetaData;
    Memo1: TMemo;
    umdCols: TUniMetaData;
    DataSource1: TDataSource;
    procedure FormShow(Sender: TObject);
    procedure UniConnection1AfterConnect(Sender: TObject);
    procedure ComboBox1Change(Sender: TObject);
    procedure DBGridEh1SelectionChanged(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form5: TForm5;

implementation

{$R *.dfm}

procedure TForm5.FormShow(Sender: TObject);
begin
  UniConnection1.Connected := True;
  If UniConnection1.Connected Then begin
    umdTables.Active := True;
    While Not umdTables.Eof Do begin
      ComboBox1.Items.Add(umdTables.FieldByName('TABLE_NAME').AsString);
      umdTables.Next;
    end;
    umdTables.Close;
  end;
  If ComboBox1.Items.Count > 0 Then
    ComboBox1.ItemIndex := 0;
end;

procedure TForm5.UniConnection1AfterConnect(Sender: TObject);
begin
  UniTransaction1.StartTransaction;
end;

procedure TForm5.ComboBox1Change(Sender: TObject);
begin
  umdCols.Close;
  umdCols.Filtered := False;
  umdCols.Filter := 'TABLE_NAME=''' + ComboBox1.Text + '''';
  umdCols.Filtered := True;
  umdCols.Open;
end;

const TRIGGER_START : String = 'SET TERM ^ ; ' + #13#10 + #13#10 +
                               'CREATE OR ALTER TRIGGER TR_LOG_[TABLE_NAME] FOR [TABLE_NAME]' + #13#10 +
                               'ACTIVE AFTER UPDATE POSITION 100' + #13#10 +
                               'AS' + #13#10 +
                               'declare variable LogStr varchar(10000);' + #13#10 +
                               'begin' + #13#10 +
                               ' Logstr = '''';';
      TRIGGER_LOG_LINE : String = ' IF (NEW.DocId <> OLD.DocId) THEN' + #13#10 +
                                  '   Logstr = :LogStr || IIF(:LogStr <> '''', '','', '''') || ''"[FIELD_NAME]":'' || ''"'' || OLD.[FIELD_NAME] || ''"'';';
      TRIGGER_LOG_END : String = ' IF (:LogStr <> '''') THEN' + #13#10 +
                                 ' BEGIN' + #13#10 +
                                 '   LogStr = ''{ "CC": {'' || :LogStr || ''}}'';' + #13#10 +
                                 '   -- INSERT CODE HERE FOR WRITING INTO THE LOGGING TABLE' + #13#10 +
                                 ' end' + #13#10 +
                                 'end^' + #13#10 + #13#10 +
                                 'SET TERM ; ^';

procedure TForm5.DBGridEh1SelectionChanged(Sender: TObject);
var i: Integer;
    sLine : String;
begin
//  sTriggerName := 'TR_LOG_' + ComboBox1.Text; // TODO: delete everything longer than 31 chars
  Memo1.Clear;
  If DBGridEh1.SelectedRows.Count > 0 Then
    Memo1.Lines.Text := TRIGGER_START;
    Memo1.Lines.Text := StringReplace(Memo1.Lines.Text, '[TABLE_NAME]', ComboBox1.Text, [rfReplaceAll, rfIgnoreCase]);
    For i := 0 To DBGridEh1.SelectedRows.Count - 1 Do begin
      umdCols.GotoBookmark(TBookmark(DBGridEh1.SelectedRows.Items[i]));
      sLine := TRIGGER_LOG_LINE;
      sLine := StringReplace(sLine, '[FIELD_NAME]', umdCols.FieldByName('Column_name').AsString, [rfReplaceAll, rfIgnoreCase]);
      Memo1.Lines.Add(sLine);
    end;
    memo1.Lines.Add(TRIGGER_LOG_END)
end;

end.

Was macht der code :

Jedesmal wenn du ein Feld an- oder abwählst in der Tabelle wird der Trigger Code mit der aktuellen Feldliste erstellt, der einen JSON string erstellt mit den alten Werten, wenn was geändert wurde, Damit hast du in der Daten-Tabelle deine aktuelle Version der Daten und mit Zeitstempel rückwärts kannst du zum Ursprung zurückkehren.

man kann noch einen Delete trigger machen mit allen Feldern, wenn man will, damit man auch bei gelöschten Registern noch Daten hat

https://puu.sh/y3FJg/e1f21a30f9.png

Geändert von MyRealName (21. Okt 2017 um 19:10 Uhr) Grund: Code/Screenshot hinzugefügt
  Mit Zitat antworten Zitat
tsteinmaurer

Registriert seit: 8. Sep 2008
Ort: Linz, Österreich
530 Beiträge
 
#5

AW: Serverseitiges Logbuch über Datenänderungen

  Alt 22. Okt 2017, 16:37
Hallo Joachim,
Zitat:
Natürlich.
  Mit Zitat antworten Zitat
ZOD

Registriert seit: 6. Mai 2009
97 Beiträge
 
#6

AW: Serverseitiges Logbuch über Datenänderungen

  Alt 23. Okt 2017, 06:32
Guten Morgen,

vielen Dank für die Tipps und Vorschläge. Ich schaue mir das an und werde mich
hier zurückmelden - sozusagen als Fortschrittsbalken .
  Mit Zitat antworten Zitat
mquadrat

Registriert seit: 13. Feb 2004
1.113 Beiträge
 
Delphi XE2 Professional
 
#7

AW: Serverseitiges Logbuch über Datenänderungen

  Alt 23. Okt 2017, 07:23
Wir haben bei unseren Desktop-Anwendungen die Variante mit den Triggern je Tabelle. Ist bei uns Grundlage für einen Replizierungslayer. Bei den Web-Anwendungen sitzt die Logik in der Datenzugriffsschicht.
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:06 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz