J'essaie d'écrire un déclencheur MySQL. J'ai deux tableaux comme celui-ci:
Table A------------------------------Table B
order_id--------sku---------------order_id----order_#----sku_copy
568---------AAA---------------568---------2345
567---------BBB---------------567---------6789-------empty column
566---------CCC---------------566---------1234
Lorsqu'un client effectue un achat, un nouvel enregistrement est ajouté à chaque table. J'ai ajouté la colonne "sku_copy" au tableau B, afin qu'elle ne soit pas remplie lorsqu'un nouvel enregistrement est créé.
Lorsqu'un nouvel enregistrement est créé, je veux que mon déclencheur copie le champ "sku" du tableau A dans le champ "sku_copy" du tableau B. Cependant, le problème que j'ai est de savoir comment structurer la condition suivante dans le déclencheur.
SI: "order_id" dans le tableau A correspond à "order_id" dans le tableau B. ALORS: copiez "sku" de cet enregistrement du tableau A vers l'enregistrement du tableau B avec le "order_id" correspondant. Les données doivent être ajoutées au tableau B "sku_copy".
J'utilise le déclencheur SQL suivant mais il donne cette erreur lors de son exécution:
"# 1363 - Il n'y a pas de VIEILLE ligne sur le déclencheur INSERT"
Voici le déclencheur:
DELIMITER $$
CREATE TRIGGER trigger_name
AFTER INSERT ON tableA
FOR EACH ROW BEGIN
INSERT INTO tableB
SET sku_copy = OLD.sku,
order_id = OLD.order_id,
order = OLD.order;
END $$
DELIMITER ;
Quelqu'un peut-il me montrer comment corriger l'erreur dans ce code ou suggérer une meilleure?
Merci pour toute aide que vous pouvez apporter.
Voici une mise à jour:
J'ai essayé ce déclencheur (ce sont les données en direct au lieu d'être simplifiées comme dans les exemples ci-dessus) mais j'obtiens un code d'erreur:
"# 1064 - Vous avez une erreur dans votre syntaxe SQL; consultez le manuel qui correspond à la version de votre serveur MySQL pour la bonne syntaxe à utiliser près de" WHERE virtuemart_order_id = new.virtuemart_order_id; END IF; END "à la ligne 7"
Voici ce déclencheur:
DELIMITER $$
CREATE TRIGGER `sku_after_update` AFTER UPDATE ON `uau3h_virtuemart_order_items`
FOR EACH ROW
BEGIN
IF (old.order_item_sku_copy != new.order_item_sku)
THEN
UPDATE uau3h_virtuemart_orders
SET order_item_sku_copy=new.order_item_sku,
WHERE virtuemart_order_id=new.virtuemart_order_id;
END IF;
END$$
DELIMITER ;
Quelqu'un a-t-il des suggestions sur la façon de faire fonctionner ce déclencheur?
Je suppose que vous apprécierez d'abord TableB car il contient le order_no. Dans ce cas, vous devez utiliser une instruction de mise à jour dans votre déclencheur au lieu d'une instruction d'insertion:
Configuration du schéma MySQL 5.6.6 m9 :
CREATE TABLE TableA(order_id INT, sku VARCHAR(10));
CREATE TABLE TableB(order_id INT, order_no VARCHAR(10),sku_copy VARCHAR(10));
GO
CREATE TRIGGER trigger_name
AFTER INSERT ON TableA
FOR EACH ROW BEGIN
UPDATE TableB
SET sku_copy = NEW.sku
WHERE order_id = NEW.order_id;
END;
GO
INSERT INTO TableB(order_id, order_no)VALUES(1,'111');
INSERT INTO TableB(order_id, order_no)VALUES(2,'222');
INSERT INTO TableB(order_id, order_no)VALUES(3,'333');
GO
INSERT INTO TableA(order_id, sku)VALUES(1,'AAA'),(2,'BBB');
(Le GO
dans cet exemple est utilisé comme séparateur de lots et n'est pas envoyé à MySQL.)
Requête 1 :
SELECT * FROM TableB;
| ORDER_ID | ORDER_NO | SKU_COPY |
----------------------------------
| 1 | 111 | AAA |
| 2 | 222 | BBB |
| 3 | 333 | (null) |
Si vous souhaitez également réagir aux mises à jour, créez simplement un AFTER UPDATE
déclencher comme ceci:
Configuration du schéma MySQL 5.6.6 m9 :
CREATE TABLE TableA(order_id INT, sku VARCHAR(10));
CREATE TABLE TableB(order_id INT, order_no VARCHAR(10),sku_copy VARCHAR(10));
GO
CREATE TRIGGER TableA_AfterInsert
AFTER INSERT ON TableA
FOR EACH ROW BEGIN
UPDATE TableB
SET sku_copy = NEW.sku
WHERE order_id = NEW.order_id;
END;
GO
INSERT INTO TableB(order_id, order_no)VALUES(1,'111');
INSERT INTO TableB(order_id, order_no)VALUES(2,'222');
INSERT INTO TableB(order_id, order_no)VALUES(3,'333');
GO
INSERT INTO TableA(order_id, sku)VALUES(1,'AAA'),(2,'BBB');
GO
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
GO
CREATE TRIGGER TableA_AfterUpdate
AFTER UPDATE ON TableA
FOR EACH ROW BEGIN
IF (OLD.sku != NEW.sku)
THEN
UPDATE TableB
SET sku_copy = NEW.sku
WHERE order_id = NEW.order_id;
END IF;
END;
GO
UPDATE TableA
SET sku = 'NEW'
WHERE order_id = 2;
GO
Requête 1 :
SELECT * FROM TableB;
| ORDER_ID | ORDER_NO | SKU_COPY |
----------------------------------
| 1 | 111 | AAA |
| 2 | 222 | NEW |
| 3 | 333 | (null) |
Dans les deux cas, les tables virtuelles NEW
et OLD
font référence à la table sur laquelle le déclencheur est défini. NEW
contient la nouvelle version de la ligne qui a été insérée ou modifiée. OLD
contient la version pré-modification de la ligne. OLD
n'est défini que dans un déclencheur de mise à jour car il n'y a pas d'ancienne version sur un insert.