【问题标题】:How to implement 2 or more triggers on mysql如何在mysql上实现2个或更多触发器
【发布时间】:2015-12-27 11:07:52
【问题描述】:

您好,这是我的tbl_patient 结构:

CREATE TABLE tbl_patient
(
    id int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
    idPatient varchar(15) DEFAULT NULL,
    namePatient varchar(40) NOT NULL,
    age int NOT NULL,
    birthDate date,
    gender varchar(15) NOT NULL,
    status varchar(15) NOT NULL,
    address varchar(255) NOT NULL,
    work varchar(25) NOT NULL,
    phone varchar(15) NOT NULL
)
ENGINE=InnoDb;

我想在 tbl_patient 上放置 2 个触发器:

CREATE TRIGGER patientTrigger
BEFORE INSERT ON tbl_patient
FOR EACH ROW
SET NEW.idPatient = CONCAT("PAS-",COALESCE((SELECT MAX(id)+1 from tbl_patient),1));

CREATE TRIGGER ageTrigger
BEFORE INSERT ON tbl_pasien
FOR EACH ROW
SET NEW.age = YEAR(CURDATE()) - YEAR(birthDate);

但是我遇到了一些错误:

1235 - 此版本的 MariaDB 尚不支持“一个表具有相同操作时间和事件的多个触发器”

如何在我的桌子上实现这 2 个触发器?

【问题讨论】:

  • 你到底想在这里做什么? (SELECT MAX(id)+1 from tbl_patient) -- 这几乎正是 AUTO_INCREMENT 所做的。但这样做的方式不安全。
  • 由于age不断变化;在SELECT 中计算它; 不要存储它。

标签: mysql sql triggers mariadb mariasql


【解决方案1】:

您可以改用computed columns

CREATE TABLE tbl_patient
(
    id int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
    idPatient varchar(15) AS (CONCAT("PAS-", id)),
    namePatient varchar(40) NOT NULL,
    age int AS (YEAR(CURDATE()) - YEAR(birthDate)),
    birthDate date,
    gender varchar(15) NOT NULL,
    status varchar(15) NOT NULL,
    address varchar(255) NOT NULL,
    work varchar(25) NOT NULL,
    phone varchar(15) NOT NULL
)
ENGINE=InnoDb;

备注:

1) 请注意,您计算年龄的代码不正确,例如(2015-12-31 和 2016-01-01)。

计算年龄的更好方法:

SELECT YEAR(NOW()) - YEAR(birthDate) - 
       (DATE_FORMAT(birthDate, '%m%d') > DATE_FORMAT(NOW(), '%m%d')) AS age

2)

CREATE TRIGGER patientTrigger
BEFORE INSERT ON tbl_patient
FOR EACH ROW
SET NEW.idPatient = CONCAT("PAS-",COALESCE((SELECT MAX(id)+1 from tbl_patient),1));

当发生多个并发 INSERT 时,解决方案很差。


编辑

当用户更新 birthDate 时,使用触发器你有更新年龄(是的,它可能会发生)。

其他可能的解决方案是简单地创建视图。

CREATE VIEW vw_patient
AS 
SELECT `id`,  `namePatient`, `birthDate`,
       `gender`, `status`, `address`, `work`, `phone`,
  CONCAT("PAS-", id) AS `idPatient`,
  YEAR(NOW()) - YEAR(birthDate) - 
       (DATE_FORMAT(birthDate, '%m%d') > DATE_FORMAT(NOW(), '%m%d')) AS `age`
FROM `tbl_patient`

SqlFiddleDemo

【讨论】:

  • 我知道了:#1901 - 'age' 列不允许使用函数或表达式
  • @ElraGhifary 这很奇怪。来自文档User-defined functions and stored functions cannot be used (built-in functions can be used)
  • 如果我将计算年龄的公式放入触发器中,“字段列表中的未知出生日期列”。我会通过创建一个新的触发器来解决这个问题,就像你写的那样命名Patient。
【解决方案2】:

尝试将两个触发器的主体合并为一个,如下所示:

CREATE TRIGGER patientTrigger BEFORE INSERT ON tbl_patient FOR EACH ROW 
BEGIN
    SET NEW.idPatient =  CONCAT("PAS-",COALESCE((SELECT MAX(id)+1 from tbl_patient),1)); 
    SET NEW.age = YEAR(CURDATE()) - YEAR(birthDate);
END

【讨论】:

  • 我在 PHPMyAdmin 中得到了这个:#1064 - 您的 SQL 语法有错误;检查与您的 MariaDB 服务器版本相对应的手册,以了解在第 3 行的 '' 附近使用的正确语法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-01
  • 1970-01-01
  • 2018-03-23
  • 1970-01-01
  • 2016-12-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多