mysql - mysql 触发器中 if else block 内的 Use Case 语句

标签 mysql triggers

我是 mysql 触发器的新手。 假设我有一个表名 teachers 包含

teacher_id,
teacher_name,
description,
student_id,
class,
student_year 

我想在教师表上创建 AFTER INSERT 和 AFTER UPDATE 触发器。 为此,我有一个名为 teacherslogs 的表,其中包含 id、teacher_id、student_year、class、student_id 列

因此,每当记录插入到教师表中时,它都应该插入到教师日志中。(对于此触发器能够写入)

但是对于更新后触发器面临的问题。

要求:

每当teachers表中的student_id发生变化时,我们需要将一条记录插入到teacherslogs中,并在教师表中对该记录的其他列进行更改 为此我写了这样的

  IF ((NEW.student_id <=> OLD.student_id) = 0) Then
    select student_id,class,student_year into student_id_,class_,year_ from `employees`.`teachers` where teacher_id = OLD.teacher_id;
    Insert into `employees`.`teacherlogs`(teacher_id,student_year,class,student_id) values (OLD.teacher_id,year_,class_,student_id_);
    END IF;

但是,每当其他列(例如 class、student_year)发生更改时,我们都需要更新该记录的 teacherslogs 表,其中 Teacher_id 和 Student_id

最终触发查询

create trigger `updateteacherlogs`
AFTER UPDATE ON `employees`.`teacher` FOR EACH ROW 
BEGIN
    DECLARE teacher_id_ int(11);
    Declare student_id_ int(11);
    Declare class_ varchar(150);
    Declare year_ int(11);
    Declare dummy tinyint;

    IF ((NEW.student_id <=> OLD.student_id) = 0) Then
    select student_id,class,student_year into student_id_,class_,year_ from `employees`.`teachers` where teacher_id = OLD.teacher_id;
    Insert into `employees`.`teacherlogs`(teacher_id,student_year,class,student_id) values (OLD.teacher_id,year_,class_,student_id_);
    ELSE
         CASE WHEN (NEW.student_year <=> OLD.student_year) = 0
         THEN update `teacherlogs` set student_year = NEW.student_year where student_id=OLD.student_id and teacher_id = OLD.teacher_id;
         WHEN (NEW.class <=> OLD.class) = 0
         THEN update `teacherlogs` set class = NEW.class where student_id=OLD.student_id and teacher_id = OLD.teacher_id
         ELSE select @dummy  END 

    end if;
END

但是我在结束时遇到异常。

这是解决我的问题的正确方法还是我们可以采取的任何其他方法?

最佳答案

语法错误的原因是您的 CASE语句需要以 END CASE; 结尾,不仅仅是 END .

我不认为CASE语句实际上满足您的要求,尽管 NEW.student_year <=> OLD.student_year然后NEW.class不会与 OLD.class 进行比较查看该值是否也需要更新。这是因为(来自 manual ):

For the second syntax, each WHEN clause search_condition expression is evaluated until one is true, at which point its corresponding THEN clause statement_list executes

您只需替换 ELSE CASE ... 即可解决这个问题与 ELSEIF子句:

ELSEIF NEW.student_year <=> OLD.student_year OR NEW.class <=> OLD.class THEN
UPDATE teacherlogs
  SET student_year = NEW.student_year, class = NEW.class 
  WHERE student_id = OLD.student_id AND teacher_id = OLD.teacher_id;

这应该有效,因为(根据我对您的数据库如何配置问题的理解)student_year 的值和classteacherlogs应该与 OLD.student_year 相同和OLD.class如果它们与 NEW.student_year 相同和NEW.class这些值不会更新。

如果我的理解不正确,您将需要修改更新以使每个值都有条件:

ELSE
    UPDATE teacherlogs
    SET student_year = IF(NEW.student_year <=> OLD.student_year, NEW.student_year, student_year),
    class = IF(NEW.class <=> OLD.class, NEW.class, class)
    -- repeat for all columns
    WHERE student_id = OLD.student_id AND teacher_id = OLD.teacher_id;
END IF;

关于mysql - mysql 触发器中 if else block 内的 Use Case 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50311592/

相关文章:

MySql 触发器问题变量未在命令字符串中引用

Android - 如何触发编辑文本字段的验证

sql - Postgresql触发器函数语法错误

mysql - 将 MySQL 更新查询转换为 sequelize 查询

mysql - 使用其他行的 SUM() 和 COUNT() 更新一行

java - 为什么 hibernate 不能执行命令

mysql - 如何创建MySQL触发器将一个表中新插入的数据复制到另一个表中

mysql - AWS数据管道-从外部源提取数据?

MySQL 工作台 : How to disable scanning of all tables during start?

java - Oracle 触发器失败的原因可能是什么?