You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Liquibase中创建SQL触发器遇语法错误 求解决方案

解决方案:Liquibase执行触发器SQL报错问题

问题原因

Liquibase默认以;作为SQL语句的分隔符,而你的触发器定义中包含多个;,导致Liquibase错误地将触发器代码拆分成多个独立语句执行,从而触发语法错误。

解决方法

方法1:自定义语句结束分隔符

在changeSet中指定自定义结束分隔符(比如//),避免Liquibase误解析触发器内部的分号:

<changeSet id="1694415120381-contract_updateTime_trigger" author="vietdq" endDelimiter="//">
    <sql>
        CREATE TRIGGER updateContractTrigger BEFORE UPDATE ON contract
            FOR EACH ROW
        BEGIN
            IF (OLD.`is_deleted` IS NOT NULL AND NEW.`is_deleted` IS NOT NULL AND OLD.`is_deleted` != NEW.`is_deleted`) THEN
               SET NEW.`deleted_time` = CURRENT_TIMESTAMP();
            ELSE
                SET NEW.`updated_time` = CURRENT_TIMESTAMP();
            END IF;
        END //
    </sql>
</changeSet>

说明:通过endDelimiter="//"告知Liquibase使用//作为整个SQL语句的结束标记,触发器内部的分号将被视为代码的一部分,不会被截断。

方法2:使用Liquibase专用createTrigger标签

优先推荐这种方式,Liquibase会自动处理数据库语法和分隔符问题,代码更易维护:

<changeSet id="1694415120381-contract_updateTime_trigger" author="vietdq">
    <createTrigger triggerName="updateContractTrigger" tableName="contract" timing="BEFORE" event="UPDATE">
        <triggerBody>
            IF (OLD.`is_deleted` IS NOT NULL AND NEW.`is_deleted` IS NOT NULL AND OLD.`is_deleted` != NEW.`is_deleted`) THEN
               SET NEW.`deleted_time` = CURRENT_TIMESTAMP();
            ELSE
                SET NEW.`updated_time` = CURRENT_TIMESTAMP();
            END IF;
        </triggerBody>
    </createTrigger>
</changeSet>

说明:createTrigger标签是Liquibase为创建触发器提供的抽象封装,会根据目标数据库自动生成正确的SQL语法,无需手动处理分隔符。

内容的提问来源于stack exchange,提问作者VieT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 15:57:19