mysql: 2 Fragen zu Triggern
Jörg
- mysql
- trigger
Hallo,
ich schaue mir gerade erstmalig Trigger in mysql an.
Sehr nützlich, wenn es um Datenintegrität geht.
Ich habe 2 Frage dazu:;
Ist es möglich, einen Trigger zu erstellen, dem egal ist, ob es um ein Insert- oder Update Statement geht oder muss ich dann auf jeden Fall 2 Trigger daraus machen?
Ich habe eine (doofe) unnormalisierte Spalte, die ich schon seit graumer Zeit mitschleppe. Diese Spalte hat kommabasiert Werte, die ansich in eine andere Tabelle normalisiert gehört hätten. Könnte ich einen Trigger gestalten, der mir aus einem Neueintrag in der "Log-Tabelle" (so nenne ich mal die Tabelle, die durch den Trigger bedient wird) so viele Eineträge macht, wie Einträge in der kommabasierten Spalte sind?
Bsp: In der Spalte stehen "test1,test2,test3" drin.
Und der Trigger würde daraus einen Insert für test1, einen für test2 und einen für test3 machen?
Geht sowas?
Jörg
Tach!
- Ist es möglich, einen Trigger zu erstellen, dem egal ist, ob es um ein Insert- oder Update Statement geht oder muss ich dann auf jeden Fall 2 Trigger daraus machen?
Dazu kannst du dir die Syntax im Handbuch anschauen. Wenn es eine syntaktisch valide Möglichkeit gibt, und der erläuternde Text nichts gegenteiliges behauptet, dann ja, ansonsten nicht.
Da die entsprechenden Syntaxelemente trigger_time und trigger_event nur einmal verwendet werden dürfen und jeweils nur einen der möglichen Werte annehmen dürfen, ist es also nicht möglich, einen Trigger für mehrere Anwendungsfälle zu verwenden. Es spricht aber nichts grundsätzlich dagegen, ein Stored Program aufzurufen, und Code damit wiederzuverwenden.
Könnte ich einen Trigger gestalten, der mir aus einem Neueintrag in der "Log-Tabelle" (so nenne ich mal die Tabelle, die durch den Trigger bedient wird) so viele Eineträge macht, wie Einträge in der kommabasierten Spalte sind?
Sollte gehen. Man kann BEGIN...END verwenden und darin alles was an Statements verfügbar ist.
dedlfix.
Hallo Jörg,
soweit ich die Syntax richtig lese, brauchst Du zwei Trigger.
Das Verteilen der Werte auf mehrere Zeilen bedeutet, dass Du den String splitten und über das Ergebnis eine Schleife laufen lassen musst. Das ist in MySQL nicht trivial, weil es keinen Array-Typ gibt und kein Gegenstück zu PHPs EXPLODE
. Eine Operation, die einen String an einem Delimiter aufteilt und daraus eine Temp-Tabelle macht, ist mir auch nicht bekannt.
Ich persönlich würde nun mit Schleifenkonstrukten und geschachteltem SUBSTRING_INDEX arbeiten. Einer, um "alle Werte bis zum x. Komma" zu holen und dann einen zweiten drumrum, um "bis zum -1 Komma" zu lesen.
SUBSTRING_INDEX('a,b,c,d', ',', 3)
ergibt "a,b,c"
- also 3 der kommaseparierten Teile.
SUBSTRING_INDEX('a,b,c', ',', -1)
ergibt "c"
- einen Teil, ab rechts.
Vorher müsste man noch die Anzahl der Kommas zählen, um zu wissen, wie oft man das machen muss.
Alternativ kann man auch in einer Schleife mit INSTR das erste Komma suchen, den Teil davor wegschreiben und mit dem Teil dahinter weitermachen. Wenn man kein Komma mehr findet, schreibt man den verbeleibenden Teil weg. Es ist jedenfalls Programmierung wie in einer Stored Procedure, und vermutlich ist es auch sinnvoll, daraus eine Stored Procedure zu machen, weil man ja zwei Trigger braucht.
Aber solche Reparaturen am offenen Herzen sind immer nur die Notlösung. Besser wäre es sicherlich, den Code zu korrigieren und die DB in einem Batch-Job zu fixen.
Rolf
Tach!
Das Verteilen der Werte auf mehrere Zeilen bedeutet, dass Du den String splitten und über das Ergebnis eine Schleife laufen lassen musst. Das ist in MySQL nicht trivial, weil es keinen Array-Typ gibt und kein Gegenstück zu PHPs
EXPLODE
.
Weil du das grad erwähnst, ich hab das vor einiger Zeit schonmal benötigt. Das Problem ist nicht neu und es existieren dazu bereits Lösungsvorschlage in den Weiten des Netzes.
dedlfix.
Hallo dedlfix und Rolf,
danke für Eure Antworten und Denkansätze.
Schade eigentlich, das wäre mein erster An- und Einsatz von GTriggern gewesen, aber so bringen sie mir dann doch nicht viel.
Deshalb habe ich in den letzten 2 Tagen meine komplette Anwendung so umprogrammiert, dass ich das über php mache, was ich eigentlich ünber die Trigger erreichen wollte. Klar, im Wesentlichen ist mein Normalisierungsfehler schuld daran, dass ich hier keine Trigger nutzen konnte. Trotzdem ein bischen schade.
Aber dann eben ein ander mal.
Jörg
Hello,
viel spannender ist es, wie man der hinter dem Trigger liegenden Procedure/Function beibringt, eine nachvollziehbare Exception auszulösen, wenn ihre Bedingugnen nicht erfüllt wurden.
Bist Du daran interssiert?
Glück Auf
Tom vom Berg
Hello,
viel spannender ist es, wie man der hinter dem Trigger liegenden Procedure/Function beibringt, eine nachvollziehbare Exception auszulösen, wenn ihre Bedingugnen nicht erfüllt wurden.
Bist Du daran interssiert?
Hi Tom,
das wäre ich, wenn ich denn Trigger genutzt hätte. Aber beim nächsten mal dann sehr gerne. 👍
Jörg