如何将触发器“如果插入”从oracle转换为mysql

Posted

技术标签:

【中文标题】如何将触发器“如果插入”从oracle转换为mysql【英文标题】:how to convert trigger 'if inserting' from oracle to mysql 【发布时间】:2020-09-13 22:42:36 【问题描述】:

我一直在尝试将触发器从 oracle 转换为 mysql/MariaDB。我还是 MySQL 的新手,所以我还在琢磨。

这是我正在执行触发器的表中的表结构:

CREATE TABLE `attendance` (
  `attendanceid` varchar(10) NOT NULL,
  `studentname` varchar(50) DEFAULT NULL,
  `classname` varchar(20) DEFAULT NULL,
  `status` varchar(20) DEFAULT NULL,
  `atdate` varchar(20) DEFAULT NULL,
  `classid` varchar(20) DEFAULT NULL
)

我已经为触发器创建了一个序列表,如下所示:

CREATE TABLE `att_seq` (
  `id` int(11) NOT NULL
)

这是来自oracle的代码:

CREATE OR REPLACE TRIGGER "STUDENT"."CLASSID" 
BEFORE INSERT ON attendance
FOR EACH ROW
declare
BEGIN
 if :new.attendanceid is null then
                  select 'ATT' || attandance_seq.nextval into :new.attendanceid from dual;

    if inserting then
            if(:new.classname = '4A') then
            :new.classid := 'CLASS401';
            end if;
            if(:new.classname = '4B') then
            :new.classid := 'CLASS402';
            end if;
             if(:new.classname = '4C') then
            :new.classid := 'CLASS403';
            end if;
    end if;
  end if;
END;
/

到目前为止,这就是我转换它的方式(p/s:“更新类..”代码是我从 oracle 中添加的新代码):

DELIMITER $$
CREATE TRIGGER att_auto_id
BEFORE INSERT ON attendance
FOR EACH ROW
BEGIN
  INSERT INTO att_seq VALUES (NULL);
  SET NEW.attendanceid = CONCAT('ATT', LPAD(LAST_INSERT_ID(), 3, '00'));
  
  IF inserting THEN
    IF new.classname = `4A` THEN
        SET new.classid = `CLASS401`;
        UPDATE class 
        SET classid = new.classid;
    END IF;
    IF new.classname = `4B` THEN
        SET new.classid = `CLASS402`;
        UPDATE class 
        SET classid = new.classid;
    END IF;
    IF new.classname = `4C` THEN
        SET new.classid = `CLASS403`;
        UPDATE class 
        SET classid = new.classid;
    END IF;
  END IF;
END $$ 

当我运行它时,我得到了这个错误:

1054 - “字段列表”中的未知列“正在插入”

如果有人可以帮助我,将不胜感激。提前谢谢你:)

【问题讨论】:

我确定你很接近。出于好奇,请ORACLE mode。 LAST_INSERT_ID 看起来不对,它来自上一个插入。 OLD.pk IS NULL 可能是确定inserting 的方法。 mariadb-10.3 也有sequence objects 不能在 NOT NULL 上插入 NULL。 【参考方案1】:

Oracle 触发器中的 inserting 关键字可帮助您确定触发器是否由插入操作调用,因为在 Oracle 中,您可以定义一个触发器以由多个事件调用(例如,在插入或更新之前)。

但是,在mysql中,触发器只能由单个事件调用,所以在mysql中不需要这个关键字。只是在您的代码中没有if inserting then 条件。

此外,格式化表中的序列值是错误的 - 要么在应用程序中显示值时格式化值,要么在声明列时使用 zerofill 属性。这样您就可以直接在表中使用 auto_increment 列。

序列表的声明缺少 auto_increment 属性。该字段也被声明为not null,因此您不能使用null 来生成新的auto_increment 值。使用可为空的字段或空值子句。

此外,我认为您也应该删除所有 update class 语句。这些语句将无条件地更新所有记录的类表中所有记录的classid字段。

【讨论】:

谢谢,它有效。也感谢您在update class 声明中指出我的错误

以上是关于如何将触发器“如果插入”从oracle转换为mysql的主要内容,如果未能解决你的问题,请参考以下文章

如何在 oracle 触发器中转换日期类型变量的时区

将SQL Server触发器转换为oracle触发器

包含列的 SQL Server 索引 - 转换为 Oracle

Oracle 触发器创建自动编号

在 Oracle 触发器中将新行转换为 XML

如何将此代码从 oracle 转换为 redshift?