SQLite - 将 MySQL 触发器转换为在 SQLite 上工作

Posted

技术标签:

【中文标题】SQLite - 将 MySQL 触发器转换为在 SQLite 上工作【英文标题】:SQLite - Converting MySQL trigger to work on SQLite 【发布时间】:2021-12-18 09:00:17 【问题描述】:

我刚开始学习 SQLite 课程,我的一项任务希望我为 SQLite 数据库创建触发器。我知道 mysql 中的某些函数不能像 IF 语句一样在 SQLite 上运行。谁能帮我把这个 MySQL 触发器代码转换为在 SQLite 上工作?

这是 MySQL 中的触发代码:(此代码已经过测试,可与 MySQL 中的同一数据库一起使用)

CREATE TRIGGER `grade_update_check` 
BEFORE UPDATE ON `highschooler`
 FOR EACH ROW BEGIN
IF (NEW.GRADE > 12) 
THEN SET NEW.GRADE = OLD.GRADE;
 END IF;
 IF (NEW.GRADE < 9) 
THEN SET NEW.GRADE = OLD.GRADE;
 END IF; 
IF (SELECT COUNT(ID) FROM highschooler WHERE name = NEW.name and grade = NEW.grade) = 1 
THEN SET NEW.GRADE = OLD.GRADE; 
END IF; 
END

这是我为同一个触发器转换的 SQLite 代码:

CREATE TRIGGER 'grade_update_check' BEFORE UPDATE ON 'Highschooler' 
BEGIN
SELECT CASE
WHEN (SELECT grade FROM Highschooler WHERE NEW.GRADE > 12) THEN SET NEW.GRADE = OLD.GRADE;
WHEN (SELECT grade FROM Highschooler WHERE NEW.GRADE < 9) THEN SET NEW.GRADE = OLD.GRADE;
WHEN ((SELECT COUNT(ID) FROM highschooler WHERE name = NEW.name and grade = NEW.grade) = 1) THEN SET NEW.GRADE = OLD.GRADE;
END;
END;

当我尝试执行它时,它会抛出 Error: near "SET": syntax error 的错误。

任何帮助或建议都非常感谢!

【问题讨论】:

【参考方案1】:

如果满足 3 个条件中的任何一个,您希望触发器中止更新操作。

这可以像这样在 SQLite 中完成:

CREATE TRIGGER grade_update_check BEFORE UPDATE ON Highschooler 
BEGIN
  SELECT 
    CASE
      WHEN NEW.GRADE < 9 OR NEW.GRADE > 12
        OR ((SELECT COUNT(ID) FROM highschooler WHERE name = NEW.name and grade = NEW.grade) = 1) 
      THEN RAISE(ABORT, 'your message here')
    END;
END;

函数RAISE(ABORT, ...) 将中止操作并且不会更新行。 您可以自定义您将收到的消息,或将其留空。

【讨论】:

如何实现SET NEW.GRADE = OLD.GRADE @kimmieRak2 我不知道。 SET NEW.GRADE = OLD.GRADE 所做的是保留当前值而不更新列。这是由 RAISE(ABORT, ..) 完成的,它会中止更新。

以上是关于SQLite - 将 MySQL 触发器转换为在 SQLite 上工作的主要内容,如果未能解决你的问题,请参考以下文章

将 MySQL 数据库转储转换为 SQLite - INSERT 语法

Mysql Workbench 将表和列转换为在 Linux (AWS -EC2) 中不起作用的小写

将使用 GROUP BY 的查询从 MySQL 转换为 Postgres 和 SQLite

Mysql 表转换成 Sqlite表

如何优雅的将数据从sqlite3迁移到mysql

将 Oracle 触发器转换为 MySql 触发器