MySQLトリガーを記述しようとしています。次のような2つのテーブルがあります。
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
顧客が購入すると、新しいレコードが各テーブルに追加されます。テーブルBに「sku_copy」列を追加したので、新しいレコードが作成されても、列にデータが入力されません。
新しいレコードが作成されたら、トリガーでテーブルAの「sku」フィールドをテーブルBの「sku_copy」フィールドにコピーします。ただし、トリガーで次の条件を構造化する方法に問題があります。
IF:テーブルAの「order_id」は、テーブルBの「order_id」と一致します。その後、「sku」をそのテーブルAレコードから、一致する「order_id」を持つテーブルBのレコードにコピーします。データをテーブルB「sku_copy」に追加する必要があります。
次のSQLトリガーを使用していますが、実行するとこのエラーが発生します。
"#1363-INSERTトリガーに古い行がありません"
これがトリガーです:
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 ;
誰かがこのコードのエラーを修正する方法を示したり、より良いものを提案したりできますか?
あなたが与えることができるあらゆる助けをありがとう。
ここに更新があります:
私はこのトリガーを試しましたが(これは上記の例のように単純化されたのではなく、ライブデータです)、エラーコードが表示されます。
"#1064-SQL構文にエラーがあります。MySQLサーバーのバージョンに対応するマニュアルで、7行目の 'WHERE virtuemart_order_id = new.virtuemart_order_id; END IF; END'の近くで使用する正しい構文を確認してください。
ここにそのトリガーがあります:
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 ;
このトリガーを機能させる方法について何か提案はありますか?
TableBにはorder_noが含まれているため、最初に評価することを想定しています。その場合は、トリガー内で挿入ステートメントの代わりに更新ステートメントを使用する必要があります。
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');
(この例のGO
は、バッチ区切り記号として使用され、MySQLに送信されません。)
クエリ1:
SELECT * FROM TableB;
結果:
| ORDER_ID | ORDER_NO | SKU_COPY |
----------------------------------
| 1 | 111 | AAA |
| 2 | 222 | BBB |
| 3 | 333 | (null) |
アップデートにも対応したい場合は、AFTER UPDATE
このようなトリガー:
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
クエリ1:
SELECT * FROM TableB;
結果:
| ORDER_ID | ORDER_NO | SKU_COPY |
----------------------------------
| 1 | 111 | AAA |
| 2 | 222 | NEW |
| 3 | 333 | (null) |
どちらの場合でも、NEW
およびOLD
仮想テーブルは、トリガーが定義されているテーブルを参照します。 NEW
には、挿入または変更された行の新しいバージョンが含まれています。 OLD
には、変更前のバージョンの行が含まれています。 OLD
は、挿入に古いバージョンがないため、更新トリガーでのみ定義されます。