2011-07-07 3 views
2

Nous sommes en train de migrer entre 2 systèmes et avons besoin de 2 champs pour l'une de nos tables de base de données qui restent toujours synchronisées. Voici la structure de la table:MySQL Trigger pour mettre à jour une nouvelle ligne

CREATE TABLE `example` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `object_id` int(11) NOT NULL DEFAULT '0', 
    `value` varchar(200) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `object_id` (`object_id`) 
); 

Chaque fois que l'un des systèmes insère une nouvelle ligne, nous devons avoir OBJECT_ID mis à id. Nous ne pouvons pas utiliser 'before insert' car la colonne id est une colonne auto_increment donc sa valeur est NULL avant l'insertion et en raison des limitations des déclencheurs MySQL 'after insert' on ne peut pas faire ce qui suit:

CREATE TRIGGER insert_example 
    AFTER INSERT ON example 
    FOR EACH ROW 
    SET NEW.object_id = NEW.id; 

Je ne peux pas mettre à jour le code pour l'un ou l'autre système donc j'ai besoin d'un moyen d'accomplir cela du côté de la base de données. Les deux systèmes vont insérer de nouvelles lignes. Comment puis-je accomplir cela?

Répondre

5

L'utilisation d'un déclencheur qui se déclenche avant l'insertion devrait faire le travail

CREATE TRIGGER insert_example 
    BEFORE INSERT ON example 
    FOR EACH ROW 
    SET NEW.object_id = NEW.id; 

EDIT:

Comme l'OP l'a souligné NEW.id ne fonctionnera pas avec l'auto-incrémentation; un pourrait utiliser le déclencheur suivant (utilisation à vos propres risques):

CREATE TRIGGER insert_example 
     BEFORE INSERT ON example 
     FOR EACH ROW 
     SET NEW.object_id = (
      SELECT AUTO_INCREMENT 
      FROM information_schema.TABLES 
      WHERE TABLE_SCHEMA = DATABASE() 
      AND TABLE_NAME = 'example' 
    ); 

Mais je préfère repenser cette exigence un peu étrange - pourquoi avez-vous besoin de la valeur pk deux fois dans le tableau?

+0

Vous ne pouvez pas utiliser auparavant puisque NEW.id est généré sur insert donc avant l'insertion sa valeur est 0. –

+0

Right ... J'ai édité ma réponse – wonk0

0

Y at-il une raison pour laquelle vous ne pouvez pas utiliser un déclencheur BEFORE INSERT?

J'ai toujours vu les déclencheurs AFTER INSERT comme une méthode pour manipuler d'autres tables plutôt que la table pour laquelle le déclencheur a été exécuté.

Règle générale, manipuler la table le déclencheur est en cours d'exécution sur = BEFORE INSERT, manipuler les autres tables AFTER INSERT :)

+0

Vous ne pouvez pas utiliser auparavant car NEW.id est généré sur l'insertion, donc avant l'insertion, sa valeur est 0. –

+0

Ah, c'est logique. négligé le fait qu'il s'agissait d'un champ auto_increment, désolé. Pensez que vous êtes un peu coincé ici alors. Y at-il de toute façon vous pourriez réparer la conception de la base de données et se débarrasser des données redondantes? (comme en normaliser un peu) – JustDanyul

+0

Non. C'est malheureusement quelque chose que nous devons vivre avec pendant la migration entre les systèmes. Un système utilise le champ ID et l'autre utilise le champ OBJECT_ID. Les deux doivent être présents et synchronisés. –

-1

Je pense que votre déclencheur ne créera jamais en premier lieu car vous ne pouvez pas référencer NEW.column_name dans un déclencheur AFTER INSERT.

Essayez de faire cela dans un déclencheur BEFORE INSERT (S'IL VOUS PLAÎT IGNORE CE FIX CAR IL NE FONCTIONNE PAS):

CREATE TRIGGER `insert_example` BEFORE INSERT ON `t` 
FOR EACH ROW 
SET NEW.`object_id` = NEW.`id`; 

S'il vous plaît changer les noms de table et de colonne selon votre schéma.

Espérons que cela aide.

+0

Vous ne pouvez pas utiliser auparavant puisque NEW.id est généré sur insert donc avant l'insert c'est la valeur 0. –

+0

C'est vrai @Russell C, je pense que j'ai mélangé 2 choses ici. En tout cas, merci de me corriger – Abhay

Questions connexes