MySQL If else构造语法



我在MySQL中的sql触发器中使用if-else构造时遇到了一些问题。下表仅用于测试。

第一张表:

CREATE TABLE `test2`.`t1` (
`c1` VARCHAR(5) NOT NULL,
`c2` VARCHAR(45) NULL,
`c3` VARCHAR(45) NULL,
PRIMARY KEY (`c1`));

我的第二张桌子:

CREATE TABLE `test2`.`t2` (
`cc1` VARCHAR(5) NOT NULL,
`cc2` VARCHAR(45) NULL,
`cc3` VARCHAR(45) NULL,
PRIMARY KEY (`cc1`));

第三种:

CREATE TABLE `test`.`t3` (
`ccc1` VARCHAR(5) NOT NULL,
`ccc2` VARCHAR(45) NULL,
`ccc3` VARCHAR(45) NULL,
PRIMARY KEY (`cc1`));

c1是cc1和ccc1的主键。

我使用的触发器是:

DROP TRIGGER IF EXISTS `test`.`t1_AFTER_UPDATE`;
DELIMITER $$
USE `test`$$
CREATE DEFINER=`root`@`localhost` TRIGGER `t1_AFTER_UPDATE` AFTER UPDATE ON 
`t1` FOR EACH ROW 
BEGIN
DECLARE start varchar(1);
set start=substring((c2),1,1);
IF(start='S') THEN
UPDATE t2
SET cc2 = NEW.c2  
WHERE cc1 = NEW.c1;
else
UPDATE t3
SET ccc2 = NEW.c2  
WHERE ccc1 = NEW.c1;
END IF;
END$$
DELIMITER ;

基本上,如果用户更新t1.c2,则必须更新t2.cc2或t3.ccc2。如果NEW.c2的t1.c2以字母S开头,则必须更新t2.cc2,否则必须更新t3.ccc2。

查询执行得很顺利,但不会让我更新c2:的值

Executing:
UPDATE `test2`.`t1` SET `c2` = '24' WHERE (`c1` = 'M123');
Operation failed: There was an error while applying the SQL script to the database.
ERROR 1054: 1054: Unknown column 'c1' in 'field list'
SQL Statement:

在触发器中,我们指的是NEW(操作后(和OLD(操作前(关键字更新/插入/删除的行中的列。

您需要使用这些关键字才能访问这些值。可以使用NEW关键字访问当前表中的c2值。您还可以通过仅在实际修改c2值时执行该操作来进一步优化。

DROP TRIGGER IF EXISTS `test`.`t1_AFTER_UPDATE`;
DELIMITER $$
USE `test`$$
CREATE DEFINER=`root`@`localhost` TRIGGER `t1_AFTER_UPDATE` AFTER UPDATE ON 
`t1` FOR EACH ROW 
BEGIN
DECLARE start varchar(1) DEFAULT NULL; -- default it to NULL
-- Check if there is any update on c2 column
IF (NEW.c2 <> OLD.c2)
-- We access the updated value of c2 using NEW keyword
SET start = SUBSTRING(NEW.c2,1,1);
END IF;
-- Do update operation on other tables only when start is not null
IF (start IS NOT NULL) THEN
IF (start = 'S') THEN
UPDATE t2
SET cc2 = NEW.c2  
WHERE cc1 = NEW.c1;
ELSE
UPDATE t3
SET ccc2 = NEW.c2  
WHERE ccc1 = NEW.c1;
END IF;
END IF;
END$$
DELIMITER ;

触发器文档中的一些值得注意的点:

在触发器主体中,OLD和NEW关键字使您能够访问受触发器影响的行中的列。旧的和新的是MySQL触发器的扩展;它们不区分大小写。

在INSERT触发器中,只能使用NEW.col_name;没有旧的一行在DELETE触发器中,只能使用OLD.col_name;没有新行。在UPDATE触发器中,可以使用OLD.col_name来引用行更新前的列和要引用的NEW.col_name行更新后的列。

除了start的定义之外,您的触发器基本上看起来还可以。列引用缺少对new.的引用我对错误消息感到困惑,该消息应该在c2而不是c1上。

在任何情况下,我都会简单地放弃它:

DELIMITER $$
USE `test`$$
CREATE DEFINER=`root`@`localhost` TRIGGER `t1_AFTER_UPDATE` AFTER UPDATE ON 
`t1` FOR EACH ROW 
BEGIN
IF (new.c2 LIKE 'S%') THEN
UPDATE t2
SET cc2 = NEW.c2  
WHERE cc1 = NEW.c1;
ELSE
UPDATE t3
SET ccc2 = NEW.c2  
WHERE ccc1 = NEW.c1;
END IF;
END$$
DELIMITER ;

您还需要修复t3的定义。主键列不存在。

最新更新