【发布时间】:2021-05-28 03:32:11
【问题描述】:
我需要在 Liquibase 中运行准备好的语句:
<changeSet id="53" author="foo">
<sql dbms="!h2, mysql" splitStatements="true">
SET @table_name = 'AUDIT_EVENT';
SET @column_name = 'ACTOR_ID';
SET @constraint_name = (
SELECT rc.CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS rc
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS kcu
ON kcu.CONSTRAINT_CATALOG = rc.CONSTRAINT_CATALOG
AND kcu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
WHERE kcu.TABLE_NAME = @table_name
AND kcu.COLUMN_NAME = @column_name
);
SET @s = concat('ALTER TABLE ', @table_name, ' DROP FOREIGN KEY ', @constraint_name);
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt
</sql>
</changeSet>
如果我将 splitStatements 设置为 true,那么我认为参数不会在语句中持续存在,所以可以理解的是,我收到一条错误消息,指出 @s 为 NULL:
Reason: liquibase.exception.DatabaseException: You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the right syntax
to use near 'NULL' at line 1 [Failed SQL: PREPARE stmt FROM @s]
如果我将 splitStatements 设置为 false,并删除除前两个 SETs 之外的所有内容,以确保不是嵌套的 SELECT 导致问题,我会得到:
Reason: liquibase.exception.DatabaseException: You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the right syntax
to use near 'SET @column_name = 'ACTOR_ID'' at line 2 [Failed SQL: SET @table_name = 'AUDIT_EVENT';
SET @column_name = 'ACTOR_ID';]
我认为 endDelimiter 默认为 ; 的问题。所以我尝试了FOO:
<sql dbms="!h2, mysql" splitStatements="false" endDelimiter="FOO">
SET @table_name = 'AUDIT_EVENT';
SET @column_name = 'ACTOR_ID';
FOO
</sql>
我得到...
Reason: liquibase.exception.DatabaseException: You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for the right syntax
to use near 'SET @column_name = 'ACTOR_ID';
FOO' at line 2 [Failed SQL: SET @table_name = 'AUDIT_EVENT';
SET @column_name = 'ACTOR_ID';
FOO]
我觉得我不明白发生了什么。我检查了 SQL 是否在 MySQL Workbench 中工作。有什么见解吗?
【问题讨论】: