如何在 MySQL 触发器中构造 IF 条件?

tk7*_*748 5 mysql trigger

我正在尝试编写一个 MySQL 触发器。我有两张这样的表:

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
Run Code Online (Sandbox Code Playgroud)

当客户进行购买时,每张表都会添加一条新记录。我已将列“sku_copy”添加到表 B,因此在创建新记录时不会填充它。

创建新记录时,我希望触发器将表 A 中的“sku”字段复制到表 B 中的“sku_copy”字段。但是,我遇到的问题是如何在触发器中构造以下条件。

如果:表 A 中的“order_id”与表 B 中的“order_id”匹配。然后:将表 A 记录中的“sku”复制到表 B 中具有匹配“order_id”的记录。数据应添加到表 B 'sku_copy'。

我正在使用以下 SQL 触发器,但在运行时出现此错误:

“#1363 - INSERT 触发器中没有 OLD 行”

这是触发器:

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 ;
Run Code Online (Sandbox Code Playgroud)

有人可以告诉我如何更正此代码中的错误或提出更好的建议吗?

感谢您提供的任何帮助。

这是一个更新:

我试过这个触发器(这是实时数据而不是上面例子中的简化)但得到一个错误代码:

“#1064 - 您的 SQL 语法有错误;请检查与您的 MySQL 服务器版本相对应的手册,以了解在第 7 行的‘WHERE dutymart_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 ;
Run Code Online (Sandbox Code Playgroud)

有没有人对如何使这个触发器工作有任何建议?

Seb*_*ine 3

我假设您会首先评估 TableB,因为它包含 order_no。在这种情况下,您需要在触发器中使用更新语句而不是插入语句:

SQL小提琴

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');
Run Code Online (Sandbox Code Playgroud)

GO本例中的 用作批次分隔符,不发送到 MySQL。)

查询1

SELECT * FROM TableB;
Run Code Online (Sandbox Code Playgroud)

结果

| ORDER_ID | ORDER_NO | SKU_COPY |
----------------------------------
|        1 |      111 |      AAA |
|        2 |      222 |      BBB |
|        3 |      333 |   (null) |
Run Code Online (Sandbox Code Playgroud)

如果您还想对更新做出反应,只需创建一个AFTER UPDATE如下触发器:

SQL小提琴

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
Run Code Online (Sandbox Code Playgroud)

查询1

SELECT * FROM TableB;
Run Code Online (Sandbox Code Playgroud)

结果

| ORDER_ID | ORDER_NO | SKU_COPY |
----------------------------------
|        1 |      111 |      AAA |
|        2 |      222 |      NEW |
|        3 |      333 |   (null) |
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,表NEWOLD虚拟表均指定义触发器的表。NEW包含已插入或更改的行的新版本。OLD包含行的更改前版本。OLD仅在更新触发器中定义,因为插入上没有旧版本。