2011-11-05 3 views
0

J'ai une table avec une colonne IsDirty que je veux être "1" lorsqu'une ligne est mise à jour, mais je veux aussi pouvoir redéfinir explicitement l'indicateur IsDirty à "0". J'ai donc créé un déclencheur:MySQL UPDATE BEFORE trigger puzzler

FOR EACH ROW 
BEGIN 

IF NEW.IsDirty = 0 AND OLD.IsDirty=1 THEN 
    SET NEW.IsDirty = 0; 
ELSE SET NEW.IsDirty = 1; 
END IF; 

END; 

Avec ce déclencheur, la mise à jour une colonne fixe la colonne IsDirty à 1. Et je peux aussi « Mettre à Jour nom_table SET IsDirty = 0 xxx = 123 » - fonctionne très bien tourner IsDirty "de".

Mais si je le fais deux fois de suite (le "UPDATE nom_table SET IsDirty = 0 WHERE xxx = 123"), il redéfinit IsDirty à 1. Faites-le à nouveau, placez-le à 0. Et d'avant en arrière, en basculant à chaque fois. En regardant mon déclencheur, je peux voir comment cela se produirait. Donc, je l'ai changé à ceci:

FOR EACH ROW 
BEGIN 

IF NEW.IsDirty = 0 AND OLD.IsDirty=1 THEN 
SET NEW.IsDirty = 0; 
ELSEIF NEW.IsDirty = 0 AND OLD.IsDirty=0 THEN 
SET NEW.IsDirty = 0; 
ELSE SET NEW.IsDirty = 1; 
END IF; 

Mais la mise à jour maintenant une colonne autre que IsDirty ne définit plus IsDirty à 1. La seule façon de le mettre à 1 est maintenant de mettre à jour la colonne IsDirty explicitement.

Qu'est-ce que je fais mal? Je veux juste que IsDirty s'allume quand une colonne est mise à jour, et soit aussi capable de l'éteindre, même deux fois de suite et de l'éteindre.

Merci pour votre aide!

Répondre

2

Eh bien, j'ai fini par faire ce déclencheur un peu différemment. Plutôt que d'essayer de déterminer si une mise à jour est simplement un changement dans les données sur la ligne, ou une modification de l'indicateur IsDirty seulement, vs les deux, ou aucune des deux ...

Je me suis retrouvé changer l'exigence à: "si vous voulez réinitialiser l'indicateur IsDirty, c'est-à-dire le mettre à zéro - puis le mettre à -1 dans l'instruction de mise à jour". Donc c'est très explicite et clair.

Alors maintenant la gâchette ressemble à ceci:

BEGIN 
    SET NEW.EffectiveDate = current_timestamp; 
    IF NEW.IsDirty = -1 THEN 
    BEGIN 
     SET NEW.IsDirty = 0; 
    END; 
    ELSE 
    SET NEW.IsDirty = 1; 
    END IF; 
END  

Et une instruction UPDATE qui veut réinitialiser la colonne IsDirty ressemble à cet exemple:

UPDATE task_set SET IsDirty = -1 WHERE CategoryID = 20