[SQL] Trigger erstellen

War-10-ck

střelec
Teammitglied
Registriert
14 Juli 2013
Beiträge
5.689
Ort
Schießstand
Guten Morgen,
ich hoffe mir kann jemand helfen, ich komm gerade nicht mehr weiter...
Ich habe eine MySQL Datenbank Version 5.5.34. Ich benötige einen Trigger der zwei Tabellen umfasst. Grob skizziert soll das am Ende so aussehen:

Tabelle1: Titel, Notiz, Status, ID...

Tabelle2: Titel, Notiz, URL...

Wenn sich in Tabelle1 der Status von 0 auf 1 ändert soll der Trigger in Tabelle2 einen Eintrag anlegen mit selben Titel und Notiz wie der betroffene Eintrag aus Tabelle1. So in etwa die vereinfachte vorgehensweise.

[src=mysql]
DROP TRIGGER IF EXISTS `trig1`;
CREATE DEFINER=`root`@`localhost` TRIGGER `trig1`
BEFORE UPDATE ON `tabelle1` FOR EACH ROW
IF NEW.state = '1' AND OLD.state = '0' THEN
INSERT INTO `db`.`tabelle2` (`titel`, `notiz`, ) VALUES ('foo', 'bar');
END IF[/src]

Wie bekomme ich nun statt den statischen Strings 'foo' & 'bar' Werte aus dem betroffenen Eintrag von Tabelle1 eingetragen?
 
Die alten bzw. neuen Werte der Zeile erhältst du über OLD.spaltenname bzw. NEW.spaltenname, welche du bereits für die state-Spalte auswertest (z.B. NEW.titel, NEW.notiz). Siehe auch .
 
  • Thread Starter Thread Starter
  • #3
Oh verdammt. Ist ja auch selbsterklärend. :m

Manchmal steht man echt auf dem Schlauch, danke Dir!

Edit: Wie schaut das aus, wenn ich Daten von anderen Tabellen verwenden möchte?
 
Wofür genau willst du Daten aus anderen Tabellen verwenden?

MfG
Mr. J
 
  • Thread Starter Thread Starter
  • #5
So ich nochmal.
Der alte Anwendungsfall hat sich jetzt aus einer neuen Anforderung heraus anders gelöst. Allerdings hab ich ein neues Problem bei einem weiteren Trigger.

[src=mysql]BEGIN
DECLARE _id INT DEFAULT 0;
DECLARE _tagid INT DEFAULT 0;
DECLARE _tagtitles VARCHAR(255) DEFAULT "";

SELECT id
FROM f76uv_content
WHERE f76uv_content.alias = NEW.alias
INTO _id;

SELECT tag_id
FROM f76uv_contentitem_tag_map
WHERE f76uv_contentitem_tag_map.content_item_id = _id
INTO _tagid;

SELECT _tagtitles =
coalesce (CASE
WHEN _tagtitles = ''
THEN title
ELSE _tagtitles + ',' + title
END
,'')
FROM f76uv_tags
WHERE f76uv_tags.id = _tagid
INTO _tagtitles;


UPDATE f76uv_menu
SET note = _tagtitles;
END[/src]

Ich denke was da ungefähr passieren soll ist ersichtlich. Probleme gibts bei der dritten SELECT Abfrage. Dort können in title mehrere Ergebnisse zurückgegeben werden. Ich möchte erreichen, dass alle Rows die dort erzeugt werden schlicht Kommasepariert als String ind _tagtitles geschrieben werden um als letzten Schritt note eben diesen String zuweisen zu können.

Hoffe, das ist halbwegs verständlich. Wenn nicht hol ich noch weiter aus, einfach nochmal nachfragen. Bei der Datenbank handelt es sich um eine von Joomla! erzeugte.
 
Du suchst wohl GROUP_CONCAT() in Verbindung mit einer GROUP-BY-Klausel, vgl. . Allerdings widerspricht dein Vorhaben dem Konzept der DB-Normalisierung, daher solltest du dir zumindest sicher sein, dass es dennoch die sinnvollste Lösung für dein Problem darstellt. Üblicherweise würde man eine N:M-Beziehung bei einer relationalen Datenbank über eine zusätzliche Tabelle abbilden.
 
  • Thread Starter Thread Starter
  • #7
Mit GROUP_CONCAT() hab ichs bereits getestet scheint aber auch nicht zu funktionieren. Ich werd einfach einen groben Denkfehler haben. Was letztendlich erreicht werden soll ist ja nur, dass wenn in der menu Tabelle ein neuer Eintrag gemacht wird ein Artikel in der content Tabelle mit dem selben Namen gesucht wird von dem werden dann die Tags gelesen und in den neuen Menueintrag ins note Feld geschrieben.

Ich werds jetzt über ein Plugin lösen. Meine rudimentären SQL-Kenntnise reichen da offenbar nicht für aus. ;)
 
Hm und warum musst du die dort zusätzlich reinschreiben?
An der stelle an der du die brauchst müsstest du doch "nur" eine SQL-Abfrage machen die die Menu-Tabelle mit der Ceontent-Tabelle joint und die Tags ausgibt wenn die 2 geforderten Spalten gleich sind (also inner join sollte passen)?
 
  • Thread Starter Thread Starter
  • #9
Die Tags werden in der Menu Komponente benötigt, welche zum Joomla! Core gehört. Da würde ich ungern an den Models rumbasteln um auf weitere Tabellen zugreifen zu können. Ist halt alles streng nach MVC implementiert.
 
am Core musst du dazu nichts ändern, theo. sollte ein überschreiben der passenden Methode reichen - aber das ist nur theorie, ich kenne das nur zu gut das sich das einfacher anhört als es ist :D
An der MVC struktur verzweifle ich auch ständig *Fg*
 
Eine datenbankbasierte Abhilfe wäre ggf. auch die Erstellung eines MySQL-Views, welches die Daten für das Joomla-Core-Modul aufbereitet. Ansonsten wäre ein Auszug aus der zu verändernden Tabelle und eine genaue Beschreibung der gewünschten Änderung hilfreich - dein Vorhaben müsste sich über GROUP_CONCAT() umsetzen lassen, sofern ich es nicht missverstehe. Auch eventuelle Fehlermeldungen wären hilfreich.
 
  • Thread Starter Thread Starter
  • #12
Sorry, dass ich erst jetzt zum Antworten komme.

Im Grunde sind für das Problem folgende vier Tabellen relevant.

f76uv_content
id | alias

f76uv_contentitem_tag_map
tag_id | content_item_id

f76uv_tags
id | title

f76uv_menu
note | alias

Der normale Workflow ist, dass man beim Anlegen eines neuen Menu-Elements über die Joomla!-GUI den Wert für note setzen kann. Ganz ohne Tags oder ähnlichem, als einfachen String. Beim Anlegen eines Content-Elements ist es möglich dieses zu taggen. Vergebene Tags für ein Content-Element werden in der f76uv_contentitem_tag_map Tabelle abgelegt (können auch mehrere sein). Definierte Tags liegen in f76uv_tags.

In meinem Fall wird jedem Menu-Element genau ein Content-Element zugeordnet, mit jeweils gleichem alias. Die Menu-Elemente werden letztendlich auf der Website für den Nutzer zur Navigation dargestellt. Klickt ein Nutzer auf ein Menu-Element möchte ich die Möglichkeit haben auf die Tags des zugehörigen Content-Elements zuzugreifen. Da ich aber streng nach MVC arbeiten muss erscheint es mir einfacher die Tags vom Content-Element direkt im Menu-Element zu speichern um so nicht extra ein neues MVC-Model anlegen zu müssen. Ich kann also letztendlich nur auf die Tabelle f76uv_menu zugreifen. Ansonsten ist Sinn und Zweck verfehlt.

Daher war die Idee bei jedem Anlegen eines Menu-Elements per Trigger nachzusehen ob ein Content-Element mit selben alias bereits existiert (muss es). Von diesem die zugehörigen Tags aus der Mappingtabelle zu holen und diese dann in note der aktuellen f76uv_menu Tabelle zu speichern. Da auch mehrere Tags vorhanden sein können müssen die Werte durch Kommata oder irgendein anderes Zeichen getrennt werden.

Hoffe, dass das hilft die Frage verständlicher zu machen.
 
Zurück
Oben