Question

Je voudrais avoir un déclencheur pour effectuer l'opération suivante pour les enregistrements insérés:

 # pseudocode
 if new.group_id is null
    set new.group_id = new.id
 else
    # don't touch it
 end

Plus clairement: disons que j'ai une table à trois colonnes: id clé primaire, id_groupe int, valeur varchar.

Quand j'insère avec id_groupe comme cela:

INSERT INTO table(value, group_id) VALUES ('a', 10)

j'aimerais avoir:

id | group_id | value
---+----------+------
 1 |       10 | a

mais quand j'omets id_groupe :

INSERT INTO table(value) VALUES ('b')

il devrait être automatiquement défini sur id de cet enregistrement:

id | group_id | value
---+----------+------
 2 |        2 | b

Est-ce possible avec un déclencheur? (Je sais que je peux mettre à jour l'enregistrement après l'insertion, mais le déclencheur serait plus pratique.)

Était-ce utile?

La solution

Je ne connais aucun moyen de faire cela dans une seule déclaration, même en utilisant un déclencheur.

La solution de déclenchement suggérée par @Lucky ressemblerait à ceci dans MySQL:

CREATE TRIGGER MyTrigger BEFORE INSERT ON MyTable
FOR EACH ROW BEGIN
  SET NEW.group_id = COALESCE(NEW.group_id, NEW.id);
END

Cependant, il y a un problème. Dans la phase BEFORE INSERT , la valeur id générée automatiquement n'a pas encore été générée. Donc, si id_groupe est nul, sa valeur par défaut est NEW.id , qui est toujours 0.

Mais si vous modifiez l'activation de ce déclencheur pendant la phase AFTER INSERT afin que vous ayez accès à la valeur générée de NEW.id , vous ne pouvez pas modifier la colonne. valeurs.

MySQL ne prend pas en charge les expressions pour le DEFAULT d'une colonne, vous ne pouvez donc pas déclarer ce comportement dans la définition de la table.

La seule solution consiste à exécuter INSERT , puis immédiatement à effectuer un UPDATE pour modifier id_groupe s'il n'est pas défini.

INSERT INTO MyTable (group_id, value) VALUES (NULL, 'a');
UPDATE MyTable SET group_id = COALESCE(group_id, id) WHERE id = LAST_INSERT_ID();

Autres conseils

Je réponds ici, comme dans la réponse acceptée, Bill Karwin :

  

Dans la phase BEFORE INSERT, la valeur id générée automatiquement n'a pas été   généré pour le moment. Donc, si group_id est null, sa valeur par défaut est NEW.id qui est   toujours 0.

J'ai une réponse à vous donner: pour OP (et les visiteurs à venir), voici quelques points: Vous ne pouvez pas mettre à jour la table à partir de laquelle le déclencheur est appelé. Pour cela, vous obtiendrez Erreur 1442 :

.
Error Code: 1442
Can't update table 'MyTable' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

1.pour mettre à jour la nouvelle ligne Utilisez le déclencheur BEFORE INSERT ON . Ainsi, vous pourrez mettre à jour tous les champs de la nouvelle ligne, qui peuvent être accessibles via l'opérateur NEW i.e.

.
set NEW.group_id = NEW.id

2.Obtenez une valeur auto_increment avant d'insérer :

SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='MyTable'

En résumé, le déclencheur SQL de 'd serait comme suit:

DELIMITER //
DROP TRIGGER IF EXISTS MyTrigger//
CREATE TRIGGER MyTrigger BEFORE INSERT ON MyTable
FOR EACH ROW BEGIN
    IF new.group_id IS NULL
        set @auto_id := (SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES
                         WHERE TABLE_NAME='MyTable' AND TABLE_SCHEMA=DATABASE() ); 
        set NEW.group_id = @auto_id;
    ENF IF;
END;
//
DELIMITER ;

Cela fonctionne pour moi

DELIMITER $
CREATE TRIGGER `myTriggerNameHere`
BEFORE INSERT ON `table` FOR EACH ROW
BEGIN
    SET NEW.group_id = IF(NEW.group_id IS NULL, LAST_INSERT_ID()+1, NEW.group_id);
END;
$
DELIMITER ;

Je crois que cela fonctionnera pour vous

j'ai deux tables

test_b: a_id, value
test_c: a_id, value

Et voici un déclencheur sur l’insert du test b. Il vérifie si a_id est null et si c'est le cas, il insère 0

CREATE TRIGGER test_b AFTER INSERT ON test_b
  FOR EACH ROW 
    INSERT INTO test_c (a_id, value) VALUES (IFNULL(NEW.a_id, 0),NEW.value)

Ce déclencheur doit faire ce que vous avez demandé.

   CREATE TRIGGER mytrigger BEFORE INSERT ON mytable
          IF new.group_id IS NULL
            SET new.group_id = new.id
          END IF
      END;

Il est copié à partir d'un exemple très similaire dans la documentation MYSQL. page.

Un déclencheur semble exagéré dans cette situation. Appliquez simplement un paramètre par défaut.

CREATE TABLE `test` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `value` varchar(100) NOT NULL,
    `group_id` TINYINT(3) UNSIGNED NOT NULL DEFAULT '2'
)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top