2016-09-07 3 views
1

mysql V 5.6mysql Auslöser: Spalte nicht Teil des Updates ist nicht null

Hallo, ich habe ein Problem mit einem Trigger BEFORE UPDATE: auf einem Tisch, ich eine Flagge defiend als tinyint, nicht null, Standardwert 1. Ich habe einen Trigger vor dem Update, der dieses Flag auf 1 setzt, wenn die Zeile aktualisiert wird. Aber ich muß auch in einem Prozess explizit das Flag auf 0 setzen, also versuchte ich, dass

create trigger t BEFORE UPDATE on table for each row 
BEGIN 
IF new.flag is NULL THEN 
    set new.flag = 1 
END IF; 

Problem: new.flag nie null ist. Überprüfung mit

IF new.flag is NULL THEN 
    set new.flag = 1 
ELSEIF new.flag = 0 THEN 
    set new.flag = 3 
END IF; 

stellen Sie die Spalte 3, wenn ich die Tabelle aktualisieren, ohne die Flagge in der Update-Abfrage inklusive. Schlimmer noch, kann ich überprüfen, gegen leere Zeichenkette nicht das Flag auf 1, als wählen zu setzen (‚‘ = 0) true zurück, wenn ein:

IF new.flag is NULL OR new.flag = '' THEN 
    set new.flag = 1 
END IF; 

Ich kann nie explizit die Flags auf 0 gesetzt. Sollte eine Spalte, die nicht Teil des Updates ist, in NEW nicht null sein? Was kann ich tun, ist es eine mysql config zu ändern?

Dank

+2

"neu" enthält die Werte, die die Zeile nach der Aktualisierung haben wird (und "alt" die Werte davor). Wenn Sie es nicht in der Abfrage festlegen, hat es den vorherigen Wert ("neu" ist nicht die Liste der Spalten, die Sie in Ihrer Aktualisierungsabfrage verwendet haben). Sie könnten z.B. 'setze flag = 3' in deiner update-Abfrage als Marker, der in deinem Trigger auf 0 gesetzt werden soll. Oder Sie möchten vielleicht Ihre Logik ändern, übliche Update-Marker sind z.B. 'timestamp' Felder mit' on update current_timestamp'. – Solarflare

+0

@Solarflare ha, setzt einen falschen Wert und dann auf 0 im Rigger scheint es zu tun: IF new.flag_indexation_required = 3 THEN neu gesetzt.flag_indexation_required = 0; ELSE neu setzen.flag_indexation_required = 1; ENDE IF; Kannst du deine Antwort hinzufügen, damit ich sie annehmen kann? – jlb

Antwort

1

NEW enthält die Werte für alle Spalten, die die Zeile nach dem Update haben, nicht nur die Werte, die Sie explizit in der Update-Abfrage verwendet.

Um dem Trigger mitzuteilen, dass Sie den Wert explizit zurücksetzen möchten, können Sie einen andernfalls nicht verwendeten (aber gültigen) Wert verwenden, um diese Informationen zu markieren. Verwenden Sie dann im Trigger, z unterzeichnet Tinyint)

IF new.flag = -1 THEN 
    set new.flag = 0; 
ELSE 
    set new.flag = 1; 
END IF; 

Dann in Ihrer update Abfrage,

update table set flag = -1; 

den Wert zu 0, einen anderen Wert gesetzt ist, oder gar nicht, dass die Spalte in Ihrer Abfrage verwenden, wird es zugesetzt.

Es gibt eine alternative und häufigere Methode ohne Trigger, die ähnlich wie Ihre Flagge funktioniert. Sie können eine Spalte

last_update datetime default null on update current_timestamp; 

null in dieser Spalte die gleiche Bedeutung wie flag = 0 hätte, jeder andere Wert die gleiche Bedeutung wie flag = 1 haben würde. Sie werden automatisch eingestellt. Wenn Sie Ihre "Flagge" zurücksetzen möchten, können Sie einfach

update table set last_update = null; 

verwenden Ihr Trigger-Ansatz wird natürlich zu gut funktionieren. Stellen Sie sicher, dass Sie dieses Verhalten irgendwo dokumentieren.

Verwandte Themen