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
相关产品推荐
相关产品推荐

