Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Trigger auf Datenbankebene? (https://www.delphipraxis.net/193414-trigger-auf-datenbankebene.html)

MES 27. Jul 2017 11:26

Datenbank: MariaDB • Version: 10.1.13 • Zugriff über: FireDac

Trigger auf Datenbankebene?
 
Hallo, ich habe folgendes Anliegen, das zunächst ganz trivial erscheinen mag.
Vorab: Ich bin kein Datenbankexperte.

Ich möchte das bei gewissen Tabellenoperationen(insert, update...) etwas in diesen Datensatz geschrieben wird.
Typische Funktion für einen (tabellenbezogenen) Trigger.

Nun will ich aber im Nachhinein nicht bei ein paar Hundert Tabellen einen Trigger hinterlegen.
Ich hätte gerne das ich das eine Ebene höher einmalig hinterlege: in der Datenbank an sich.

Wie kann ich also auf der Datenbankebene das Ereignis "User xx hat in der Tabelle yy einen Datensatz hinzugefügt" abfangen um dann wiederum auf diese Tabelle/Datensatz zuzugreifen
und entsprechende Einträge(z.B. Username und Datum) vorzunehmen.

(Mein Ansatz: Die Datenbank überwacht doch soweiso alles was in den Tabellen passiert - über z.B. die Sicherheit. Aber WIE zapf ich das an?)

Danke für eure Hilfe.

himitsu 27. Jul 2017 11:43

AW: Trigger auf Datenbankebene?
 
Ich wüsste jetzt nicht, dass sowas im SQL geht.

Aber du kannst dir über ein SELECT alle Tabellen auflisten lassen und dann für jede Tabelle ein CREATE TRIGGER ausführen und so deine Trigger-Funktion überall dran hängen.

MES 27. Jul 2017 12:07

AW: Trigger auf Datenbankebene?
 
Mein Problem ist das ich in den Datensatz den Benutzername eintragen will. Dieser ist aber der Name mit der er sich in der Anwendung
angemeldet hat und nicht der mit dem in der Datenbank angemeldet ist.

Ich müsste also dem (Tabellen)Trigger einen Parameter übergeben(Username) - und da scheitere ich.

Ich hatte die Idee eine "Übersetzungspabelle" beim Anmelden in die Anwendung zu pflegen.
Da steht dann drin dass der Datenbankuser_xx den Anwendung_Username_yy hat(wird beim ausloggen wieder gelöscht).
Der Trigger sollte nun in dieser Tabelle nachschauen wie der Anwendung_Username lautet und diesen Namen dann in den betroffenen Datesatz posten.

Da die Einträge in jeder Tabelle identisch sind(Name, Datum) brauche ich nur einen Trigger (oder eine SP).

Nersgatt 27. Jul 2017 12:17

AW: Trigger auf Datenbankebene?
 
Zitat:

Zitat von MES (Beitrag 1377593)
Ich hatte die Idee eine "Übersetzungspabelle" beim Anmelden in die Anwendung zu pflegen.
Da steht dann drin dass der Datenbankuser_xx den Anwendung_Username_yy hat(wird beim ausloggen wieder gelöscht).
Der Trigger sollte nun in dieser Tabelle nachschauen wie der Anwendung_Username lautet und diesen Namen dann in den betroffenen Datesatz posten.

So würde ich es machen, allerdings würde ich nicht den Datenbankuser als Schlüssel verwenden, sondern die Connection_id(). Damit funktioniert das dann auch, wenn mehrer Leute sich mich dem selben Datenbankuser anmelden, aber mit verschiedenen Namen in der Anwendung.

Ich glaub aber mit Deiner Trigger-über-alle-Tabellen-Idee sieht es schlecht aus. Das wirst Du einzeln machen müssen.

himitsu 27. Jul 2017 12:22

AW: Trigger auf Datenbankebene?
 
Im CREATE TRIGGER kann man je nach DBMS einen Funktions-Aufruf oder gar ein "beliebiges" SQL-Statement ausführen. (meistens sind die Trigger-Funktionen ohne Parameter und haben nur die impliziten Parameter wie NEW, OLD usw., aber man kann fast immer auch weitere Parameter in die Funktion einbauen und beim Aufruf übergeben)
Das wird aber alles User-unabhängig in der DB registriert und ausgeführt.

Du könntest eine Session-Variable (falls MariaDB sowas kennt) nach dem DB-Connect setzten und Diese in dem Trigger verwenden.

Uwe Raabe 27. Jul 2017 12:45

AW: Trigger auf Datenbankebene?
 
Wäre ein zentrales BeforePost-Event auf Programmebene eventuell eine Alternative? Das wäre zudem noch datenbankunabhängig.

mikhal 27. Jul 2017 12:47

AW: Trigger auf Datenbankebene?
 
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.

Grüße
Mikhal

Da war einer schneller...

MES 27. Jul 2017 13:15

AW: Trigger auf Datenbankebene?
 
Zitat:

Zitat von himitsu (Beitrag 1377599)
Im CREATE TRIGGER kann man je nach DBMS einen Funktions-Aufruf oder gar ein "beliebiges" SQL-Statement ausführen. (meistens sind die Trigger-Funktionen ohne Parameter und haben nur die impliziten Parameter wie NEW, OLD usw., aber man kann fast immer auch weitere Parameter in die Funktion einbauen und beim Aufruf übergeben)
Das wird aber alles User-unabhängig in der DB registriert und ausgeführt.

In meinem Fall ist es MariaDB.
Was genau meinst du mit "weitere Parameter"? Man kann dem Trigger ohne Umwege ja keine Parameter übergeben.
Oder meinst du damit eine Funktion/Prozedur die innerhalb eines Triggers aufgerufen wird?

mkinzler 27. Jul 2017 13:43

AW: Trigger auf Datenbankebene?
 
Mit MariaDB hast Du da wohl schlechte Karten


Zitat:

Zitat von https://mariadb.com/kb/en/mariadb/trigger-limitations/
Each table can have only one trigger for each timing/event combination (ie: you can't define two BEFORE INSERT triggers for the same table).
..
Triggers cannot operate on any tables in the mysql, information_schema or performance_schema database.


MES 27. Jul 2017 14:38

AW: Trigger auf Datenbankebene?
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1377601)
Wäre ein zentrales BeforePost-Event auf Programmebene eventuell eine Alternative? Das wäre zudem noch datenbankunabhängig.

Wie kann ich die realisieren?

himitsu 27. Jul 2017 14:47

AW: Trigger auf Datenbankebene?
 
CREATE TRIGGER wirft da aber doch hoffentlich einen Fehler, wenn man einen zweiten Trigger erstellen will? :stupid:

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();

mkinzler 27. Jul 2017 14:47

AW: Trigger auf Datenbankebene?
 
Oder über Monitoring der Zugriffskomponenten

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

Uwe Raabe 27. Jul 2017 15:42

AW: Trigger auf Datenbankebene?
 
Zitat:

Zitat von MES (Beitrag 1377622)
Zitat:

Zitat von Uwe Raabe (Beitrag 1377601)
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.

jobo 27. Jul 2017 15:57

AW: Trigger auf Datenbankebene?
 
Zitat:

Zitat von himitsu (Beitrag 1377626)
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.

nahpets 27. Jul 2017 16:27

AW: Trigger auf Datenbankebene?
 
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.

himitsu 27. Jul 2017 17:09

AW: Trigger auf Datenbankebene?
 
Zitat:

Zitat von jobo (Beitrag 1377636)
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.

p80286 27. Jul 2017 18:43

AW: Trigger auf Datenbankebene?
 
Zitat:

Zitat von mikhal (Beitrag 1377602)
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

mikhal 27. Jul 2017 19:07

AW: Trigger auf Datenbankebene?
 
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

jobo 28. Jul 2017 08:25

AW: Trigger auf Datenbankebene?
 
Zitat:

Zitat von mikhal (Beitrag 1377656)
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.

Zitat:

Zitat von himitsu (Beitrag 1377646)
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.

p80286 28. Jul 2017 11:50

AW: Trigger auf Datenbankebene?
 
Zitat:

Zitat von jobo (Beitrag 1377674)
(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

jobo 28. Jul 2017 13:01

AW: Trigger auf Datenbankebene?
 
Zitat:

Zitat von p80286 (Beitrag 1377689)
Zitat:

Zitat von jobo (Beitrag 1377674)
(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

Ja, könnte... aber diese Diskussion ist irgendwie .. ich weiß auch nicht.
Es gibt halt Freunde der Persistenzsysteme, die DB Blackbox Fans usw. die einfach die DB tauschen können. Und es gibt die sagen wir "traditionelle" Seite. Da würde ich mich auf jeden Fall einsortieren. Sicher gibt es auch Kompromisse. Ein App Server an einer DB ist für sich genommen auch ein C/S System, dass man nach den klassischen Regeln fahren kann.
Es spricht ja nichts dagegen, andere Wege zu gehen oder andere Prioritäten zu setzen. Man muss sich halt bewusst sein, was das bedeutet.

Offenbar ist es ja wohl so, dass viele Delphi im DB Bereich so einsetzen, dass die komplette Business Logik in der Anwendung liegt. Bei spezialisierten, homogenen Systemen ist das wohl okay. Und es hat ja durchaus ein paar positive bzw. willkommene Nebeneffekte. Die Business Logik und die Constraints kann mir keiner "klauen" oder einfach per Datenmodell kopieren.

Ich habe schon high end Systeme gesehen, wo mir schlecht wurde, kein einziger Konstraint, auch nicht für foreign keys, fürchtliche Namensgebung, also inkonsistent usw usf.
Und da kann man doch nur zu dem Schluss kommen, dass es primär um Obfuscation geht.

Solange ich Robustheit, Transaktionssicherheit, Konsistenz gewährleisten kann ist ja alles gut.
Ich habe allerdings oft den Eindruck, dass die Probleme vielen gar nicht so klar sind. Ebensowenig die Möglichkeiten die ein stinknormales DB System von Haus aus bietet.
Und zur Großschreibung: wahrscheinlich mach ich mich mit Beiträgen wie diesen eh schon zum Affen.

p80286 28. Jul 2017 13:43

AW: Trigger auf Datenbankebene?
 
Zitat:

Zitat von jobo (Beitrag 1377698)
Offenbar ist es ja wohl so, dass viele Delphi im DB Bereich so einsetzen, dass die komplette Business Logik in der Anwendung liegt. Bei spezialisierten, homogenen Systemen ist das wohl okay. Und es hat ja durchaus ein paar positive bzw. willkommene Nebeneffekte. Die Business Logik und die Constraints kann mir keiner "klauen" oder einfach per Datenmodell kopieren.

Ja so etwas gibt/gab es, und aus bitterer Erfahrung, das ist nicht optimal.
Sobald irgendetwas (und sei es das Antwortverhalten) die Kommunikation zwischen Client und Server stört, bekommst die Datenhack.

Zitat:

Zitat von jobo (Beitrag 1377698)
Ich habe schon high end Systeme gesehen, wo mir schlecht wurde, kein einziger Konstraint, auch nicht für foreign keys, fürchtliche Namensgebung, also inkonsistent usw usf.
Und da kann man doch nur zu dem Schluss kommen, dass es primär um Obfuscation geht.

Nö eher 2...9 Programmierer die jeweils ein Stückchen angeflickt haben, und wo jeder ein individuelles Verhältnis zur Aufgabenstellung hat(te)
[Welcher Chef will schon eine DB verbessern, wenn es bisher auch so ohne große Probleme ging?]

Zitat:

Zitat von jobo (Beitrag 1377698)
Solange ich Robustheit, Transaktionssicherheit, Konsistenz gewährleisten kann ist ja alles gut.
Ich habe allerdings oft den Eindruck, dass die Probleme vielen gar nicht so klar sind. Ebensowenig die Möglichkeiten die ein stinknormales DB System von Haus aus bietet.
Und zur Großschreibung: wahrscheinlich mach ich mich mit Beiträgen wie diesen eh schon zum Affen.

Solange jemand weiß was er tut.... das geht so lange gut, bis jemand abschreibt und nicht genau weiß was er tut...

Darum ein solidarisches OinkOink
K-H

P.S.
@all Nein, das ist kein Rundumschlag, und ich weiß, daß hier genug Leute mitlesen, die das nicht für die Erbsenzählerei von ein paar Spinnern abtun.

nahpets 28. Jul 2017 14:40

AW: Trigger auf Datenbankebene?
 
Zitat:

Zitat von jobo (Beitrag 1377698)
Und zur Großschreibung: wahrscheinlich mach ich mich mit Beiträgen wie diesen eh schon zum Affen.

Nein, absolut nicht. Im Gegenteil, es ist erfrischend, wenn man mal fundiertes KnowHow zu lesen bekommt.

Mein Eindruck aus ca. 30 Jahren Programmiererfahrung ist eher, dass ein nicht unerheblicher Teil der Programmierer (die ich habe kennen lernen dürfen, also nicht allgemeinglobalgalaktisch) und die Software schrieben, deren Datenhaltung eine Datenbank voraussetzte, über erschreckend geringe Datenbankkenntnisse verfügten.
Daraus resultiert dann eben auch, dass man alles im Programm macht (egal welche Mengengerüste da zu verarbeiten sind) und die Datenbanklogik gegen 0 tendiert. Hauptsache die Daten sind irgendwie in der Datenbank und können mit "dem eigenen Programm" sinnvoll verarbeitet werden.

Aber das jetzt weiter auszuführen wäre arg OffTopic.

jobo 29. Jul 2017 06:27

AW: Trigger auf Datenbankebene?
 
Hach, soviel Zuspruch ist schon irgendwie tröstlich.
:)
Aber es geht ja nicht um meine Bedenkenträgerschaft. Und bis jetzt kam noch kein Hinweis, dass all die Einwände berechtigt sind. Also ist es eine Standalone Anwendung oder nicht,,
Die Frage wäre, ob der TE noch mitverfolgt, was hier geschrieben wird, bzw. ob man noch konkrete Hilfestellung leisten kann oder er schon "geflüchtet" ist.

Dazu ein Vorschlag was die "Parameter" Frage angeht.
Wenn es eine Mapping Tabelle gibt, die gepflegt ist, kann ich eine Funktion schreiben, die mir den gemappten User anhand des eingeloggten Users liefert. Die rufe ich im Triggerbody auf und hab was ich brauche, ohne Parameter.
Dann ist es nur etwas Fleißarbeit, alle Trigger zu schreiben (oder zu generieren). Einzige(?) Voraussetzung wäre dann nur, dass nicht bereits Trigger vorhanden sind. Die müssten man dann bei Mariadb offenbar mergen?

nahpets 29. Jul 2017 09:19

AW: Trigger auf Datenbankebene?
 
Ausgehend von https://mariadb.com/kb/en/sql-99/act...n-of-triggers/ kann man bei MariaDB mehrere Trigger für eine Tabelle erstellen, die nacheinander abgearbeitet werden.

Gegeben sei:
SQL-Code:
CREATE TRIGGER Trigger_1 AFTER UPDATE ON Table_1 ...;

CREATE TRIGGER Trigger_2 BEFORE UPDATE ON Table_1 ...;

CREATE TRIGGER Trigger_3 AFTER UPDATE ON Table_1 ...;
Zuerst wird Trigger_2 ausgeführt, dann Trigger_1 und anschließend Trigger_3.

Wenn ich das halbwegs richtig sehe, müsste man hier also automatisch für alle Tabellen einen zusätzlichen Trigger generieren können, der, da zuletzt erstellt, auch zuletzt ausgeführt wird. Im Trigger kann man dann eine Funktion aufrufen, die den Usernamen, auf einem der hier bereits beschriebenen Wege, ermittelt und in die Datenbank schreibt.

Ungefähr sowas sollte sinngemäß gehen:
SQL-Code:
CREATE TRIGGER Tabellenname_Insert
BEFORE INSERT ON Tabellenname
  REFERENCING NEW ROW AS New
FOR EACH ROW
BEGIN ATOMIC
  SET New.UserName = FuntionZurBenutzernemenermittlung;
  SET New.Datum = Current_Date;
END
Was ich nicht habe finden können ist, ob ein Trigger auch für mehrere Ereignisse aufgerufen werden kann, also ein

SQL-Code:
BEFORE INSERT OR UPDATE ON Tabellenname


Es scheint aber eher nicht der Fall zu sein, so dass halt je Tabelle zwei Trigger benötigt werden:
SQL-Code:
CREATE TRIGGER Tabellenname_Insert BEFORE INSERT ON Tabellenname

CREATE TRIGGER Tabellenname_UPDATE BEFORE UPDATE ON Tabellenname
Inhaltlich können sie identisch sein.

Die oben verlinkte Dokumentation zu MariaDB ist sehr ausführlich und sollte für alle MariaDB-Nutzer zur Pflichtlektüre gehören und als ersten Anlaufstelle bei Fragen dienen.

Der Triggerquelltext läßt sich vermutlich sogar per SQL über INFORMATION_SCHEMA.TABLES generieren, sowas in der Art:
SQL-Code:
select
  ConCat('CREATE TRIGGER TRI_',Table_Name,
  ' BEFORE INSERT ON ',Table_Name,
  ' REFERENCING NEW ROW AS New FOR EACH ROW',
  ' BEGIN ATOMIC',
  ' SET New.UserName = FuntionZurBenutzernemenermittlung;'
  ' SET New.Datum = Current_Date;',
  ' END') as SQL_Statement
from INFORMATION_SCHEMA.TABLES
where TABLE_SCHEMA = 'DasBenutzerSchema'
and  Table_Name like 'ErforderlicheEinschränkungFürBenötigteTeilmenge%';
Das Ergebnis müsste man dann irgendwie per Batch oder so abarbeiten.

Eventuell ginge es auch innerhalb einer Prozedur über Execute Immediate (https://mariadb.com/kb/en/mariadb/execute-immediate/), aber da hab' ich jetzt keine Lust, das herauszufinden.

mkinzler 30. Jul 2017 13:59

AW: Trigger auf Datenbankebene?
 
Dann wäre die folgende Aussage falsch:

https://mariadb.com/kb/en/mariadb/trigger-limitations

jobo 30. Jul 2017 14:20

AW: Trigger auf Datenbankebene?
 
Interessant, dann würde ich wohl eher den offiziellen Limitations folgen, als dem Nachdruck eines SQL 99 Buches von dem auf der Seite geschrieben steht:
Zitat:

This page is part of the book SQL-99 Complete, Really, by Peter Gulutzan & Trudy Pelzer. The authors have graciously allowed us to reproduce the contents of the book here. Because the book is about the SQL-99 standard, the contents of this and other pages in the book may not directly apply to MariaDB. Use the navigation bar to navigate the book.

nahpets 30. Jul 2017 14:28

AW: Trigger auf Datenbankebene?
 
Die beiden Seiten Trigger Limitations und Activation of Triggers scheinen sich in ihren Aussagen zu widersprechen.

Ok, wenn man weiterliest: Der zweite Link bezieht sich auf den SQL-99-Standard. Das dort beschriebene muss nicht zwingend mit MariaDB funktionieren.

Hiernach scheint es aber ab MariaDB 10.2.3 zu funktionieren: Information Schema TRIGGERS Table
Zitat:

Zitat von ACTION_ORDER
Indicates the order that the action will be performed in (of the list of a table's triggers with identical EVENT_MANIPULATION and ACTION_TIMING values). Before MariaDB 10.2.3 introduced the FOLLOWS and PRECEDES clauses, always 0



Alle Zeitangaben in WEZ +1. Es ist jetzt 15:42 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