AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Trigger auf Datenbankebene?
Thema durchsuchen
Ansicht
Themen-Optionen

Trigger auf Datenbankebene?

Ein Thema von MES · begonnen am 27. Jul 2017 · letzter Beitrag vom 30. Jul 2017
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#11

AW: Trigger auf Datenbankebene?

  Alt 27. Jul 2017, 15:47
CREATE TRIGGER wirft da aber doch hoffentlich einen Fehler, wenn man einen zweiten Trigger erstellen will?

Meistens hat man doch in etwa sowas:
SQL-Code:
CREATE FUNCTION TriggerFunction() ...;
CREATE TRIGGER TriggerName ON Table ... DO TriggerFunction();
Bei einigen DBMS kann man da aber auch Parameter bei den Trigger-Funktionen nutzen.
SQL-Code:
CREATE FUNCTION TriggerFunction(Param VARCHAR) ...;
CREATE TRIGGER TriggerName ON Table ... DO TriggerFunction('abc');
Und die selbe Trigger-Funktion kann man auch an mehrere Tabellen hängen.
Es gibt fast immer irgendwelche virtuellen Datenbank-Schema-Tabellen, wo man eine Liste aller aktuell existierenden Tabellen auslesen kann
und dann entweder clientseitig oder DB-seitig über einen EXECUTE-Befehl nacheinander die vielen CREATE TRIGGER zusammensetzen und ausführen.
SQL-Code:
CREATE FUNCTION TriggerFunction() ...;
CREATE TRIGGER TriggerName ON TableA ... DO TriggerFunction();
CREATE TRIGGER TriggerName ON TableB ... DO TriggerFunction();
CREATE TRIGGER TriggerName ON TableC ... DO TriggerFunction();
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (27. Jul 2017 um 15:58 Uhr)
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.858 Beiträge
 
Delphi 11 Alexandria
 
#12

AW: Trigger auf Datenbankebene?

  Alt 27. Jul 2017, 15:47
Oder über Monitoring der Zugriffskomponenten

http://docwiki.embarcadero.com/RADSt...chung_(FireDAC)
Markus Kinzler

Geändert von mkinzler (27. Jul 2017 um 15:50 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#13

AW: Trigger auf Datenbankebene?

  Alt 27. Jul 2017, 16:42
Wäre ein zentrales BeforePost-Event auf Programmebene eventuell eine Alternative? Das wäre zudem noch datenbankunabhängig.
Wie kann ich die realisieren?
Hängt von deiner Arbeitsweise ab. Wenn z.B. alle Queries statisch in Datenmodulen liegen, kann man diese von einem gemeinsamen Vorfahren ableiten, der sich in das BeforePost-Event reinhängt. Alternativ wäre auch eine Interposer-Class denkbar, die das DoBeforePost überschreibt. Die Unit könnte in etwas so aussehen und müsste dann in den gewünschten Fällen in der Uses-Anweisung hinter FireDAC.Comp.Client aufgeführt werden. Das funktioniert allerdings nicht bei expliziten UPDATE Queries, sondern nur bei Verwendung der DataSet-Methoden Insert, Edit und Post.

Delphi-Quellcode:
unit FDQueryInterposer;

interface

type
  TFDQuery = class(FireDAC.Comp.Client.TFDQuery)
  protected
    procedure DoBeforePost; override;
  end;

implementation

procedure TFDQuery.DoBeforePost;
begin
  { hier bei Bedarf die entsprechenden Felder setzen }
  inherited;
end;

end.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
jobo

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

AW: Trigger auf Datenbankebene?

  Alt 27. Jul 2017, 16:57
Meistens hat man doch in etwa sowas:
@himitsu
wenn ich das richtig im Kopf habe, arbeitest Du häufig mit Postgres? Da kann man beliebige Triggerfunktionen an den Trigger hängen, auch für mehrere Trigger/Tabellen die gleiche Triggerfunktion.
Hab ich neulich noch für eine Log Funktion/Werteänderung gemacht.

Das geht aber so easy nicht mit jeder Datenbank.

Um es straight forward zu lösen, müsste m.E. tatsächlich ein Usermapping mit einer Tabelle, die aktive Sitzungen notiert, erfolgen. Daraus könnte sich dann ein Insert/Update/ Trigger pro Tabelle bedienen (delete fällt ja weg bei der Konstruktion).

Ich habe bei dem erwähnten Log Mechnismus oben, nach der Erstellung der Trigger "blinde Updates" (alter Wert = neuer Wert) über alle relevanten Daten laufen lassen und so nachträglich mit etwas Handarbeit "historische" Logdaten für initiales Insert und Update (=StatusQuo) erzeugt.
Nicht geloggte Userdaten usw. lassen sich damit natürlich im Nachhinein nicht erfinden.
Aber man hat dennoch für künftiges Reporting einen einheitlichen Stand.

In einem reinen C/S System mit nur einem Client (einer Art) kann man natürlich auch über den Client arbeiten. Hier kann man auch problemlos weitere Daten verwenden, Rechnername usw. bei Mehrfachanmeldung oder was man so braucht.
Gruß, Jo
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#15

AW: Trigger auf Datenbankebene?

  Alt 27. Jul 2017, 17:27
Eine BeforePost-Methode kann man mehreren Datenbankkomponenten zuweisen.

Beispiel:
Delphi-Quellcode:
type
  TForm1 = class(TForm)
    qryAnschriften: TZQuery; // oder sonstein genutzter Komponententyp
    qryRechnungen: TZQuery; // oder sonstein genutzter Komponententyp
...
    procedure AnyTableBeforePost(DataSet: TDataSet);
...

procedure TForm1.FormCreate(Sender: TObject);
begin
  qryAnschriften.BeforePost := AnyTableBeforePost;
  qryRechnungen.BeforePost := AnyTableBeforePost;
  ...
end;

procedure TForm1.AnyTableBeforePost(DataSet: TDataSet);
begin
  DataSet.FieldByName('Username').AsString := DeineGetUserNameFunktionOderVariabelOderSowas;
  DataSet.FieldByName('Datum').AsString := Now;
end;
Nachteil: Wird, am Programm vorbei, direkt auf der Datenbank gearbeitet oder mit anderen Clients, fehlen die im BeforePost gesetzten Informationen natürlich.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#16

AW: Trigger auf Datenbankebene?

  Alt 27. Jul 2017, 18:09
arbeitest Du häufig mit Postgres? Da kann man beliebige Triggerfunktionen an den Trigger hängen, auch für mehrere Trigger/Tabellen die gleiche Triggerfunktion.
Hab ich neulich noch für eine Log Funktion/Werteänderung gemacht.
Die Dokumentation von z.B. MSSQL hat das ähnlich.
https://docs.microsoft.com/en-us/sql...r-transact-sql
Hier klingt es sogar danach, dass man auch direkt ganze SQL-Statements da ausführen lassen kann, anstatt nur eine TriggerFunktion aufzurufen.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#17

AW: Trigger auf Datenbankebene?

  Alt 27. Jul 2017, 19:43
Ich würde es im Programm realisieren: In deiner Zugriffskomponente (vermutlich Query) gibt es das Event BeforePost, hier kannst du den Benutzernamen ermitteln und in die gewünschten Tabellenfelder eintragen.
Dann ist aber jeder DB-Nutzer, der Dein Programm nicht nutzt, außen vor. Darüber muß man sich im klaren sein.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von mikhal
mikhal

Registriert seit: 11. Sep 2003
Ort: Linz am Rhein
796 Beiträge
 
Delphi 11 Alexandria
 
#18

AW: Trigger auf Datenbankebene?

  Alt 27. Jul 2017, 20:07
Ja, das ist wohl so. Aber eine solche Forderung geht aus der Frage des TE nicht hervor. Wahrscheinlich wurde die Anforderung erst später angefragt.

Grundsätzlich ist die Verwendung eines Datenbank-Triggers hier der bessere Weg, wenn man diese Daten grundsätzlich bei jedem Insert- oder Update-Statement verwenden möchte. Aber dann benötigt der TE eine Tabelle mit den Benutzern, gegen die sich die Anwender anmelden müssen, damit er die Namen ziehen kann. War auch mein erster Gedanke, aber ist wohl beim TE nicht vorgesehen oder war nicht geplant. Wenn ich es richtig verstanden habe, werden DB-User angemeldet, die über eine Rolle verfügen. Und ja, er muss die Trigger für jede Tabelle anlegen, ein Aufwand, den er nicht treiben wollte.

Über das Event muss er das dann aber auch machen, kann aber wie oben beschrieben eine Standard-Routine verwenden, um den Aufwand zu reduzieren.

Grüße
Mikhal
Michael Kraemer
Computer erleichtern die Arbeit...
...und die Erde ist eine Scheibe!
  Mit Zitat antworten Zitat
jobo

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

AW: Trigger auf Datenbankebene?

  Alt 28. Jul 2017, 09:25
Ja, das ist wohl so.
..

Grundsätzlich ist die Verwendung eines Datenbank-Triggers hier der bessere Weg,
..
Klar, ein Server ist ein Server.
Wenn es wasserdicht sein soll, müssen solche Operationen auf dem DB Server erfolgen.

Wenn ich ein C/S System so definiere, dass mein (Delphi)Client den einzigen Zugriff hat (und diesen Zustand auch erfolgreich sicherstellen kann), dann kann ich natürlich hier alle möglichen Mätzchen machen, von Logging bis Business Logic.
Sobald mehr als ein System auf die DB durchgreift (vor allem schreibend), bin ich natürlich gekniffen. Theoretisch entgleitet das bereits, wenn ich einen Release Candidate des gleichen Sytems auf eine Produktivdb loslasse. Naja, ich will den Teufel nicht an die Wand malen. Wenn man weiß was man tut, ist vieles möglich.

Ich hatte allerdings die Anforderung des TE so verstanden, dass er nicht alle / so viel Altdaten "nachverarbeiten" will. Aber vlt geht es darum gar nicht.

Die Dokumentation von z.B. MSSQL hat das ähnlich.
Ja, kann sein. Ich hab keinen so detailierten Überblick was die DB auf Triggerebene alles können / unterscheidet.
Aber das von Dir erwähnte Verfahren kenne ich so halt von Postgres und eben nicht von Maria.
Gruß, Jo

Geändert von jobo (28. Jul 2017 um 09:27 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#20

AW: Trigger auf Datenbankebene?

  Alt 28. Jul 2017, 12:50
(und diesen Zustand auch erfolgreich sicherstellen kann)
Um die Bedeutung zu unterstreichen hättest Du einen etwas größeren Font wählen sollen.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 08:00 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz