Liquibase:MySQL存储过程中的SQL语法错误

时间:2017-09-07 15:50:18

标签: mysql sql stored-procedures syntax liquibase

我试图通过Liquibase运行MySQL存储过程SQL脚本,但从未工作过。

db.storedprocedure.xml 的内容:

$$

CREATE PROCEDURE `liqui01`.`User_Search`(
    INOUT id INT,
    OUT name VARCHAR(50)
)
BEGIN

    SET @sql = CONCAT("SELECT id, name FROM user WHERE da.MarketId = ", id );

    PREPARE stmt from @sql;
    EXECUTE stmt;

END$$

我的SQL文件 change_03.sql 的内容:

<sql>

它显示如下错误:

  

运行Liquibase时出现意外错误:SQL中有错误   句法;查看与MySQL服务器版本对应的手册   正确的语法在&#39; $$ ...

附近使用

我试图改变&#34; $$&#34;到其他分隔符,或将SQL放在XML文件的{{1}}标记内,都没有用。

任何建议都将不胜感激!

更新1

@Shadow给出了正确的答案(遗憾的是我无法将其标记为答案,因为它在评论中),从sql脚本中删除分隔线将使其正常工作,感谢他!

现在的问题是:如何使用&#34; endDelimiter&#34;参数β

2 个答案:

答案 0 :(得分:0)

liquibase internals将delimiter命令添加到命令的开头,您必须使用$$删除或评论第一行:

-- $$

CREATE PROCEDURE `liqui01`.`User_Search`(

...

END$$

答案 1 :(得分:0)

我在互联网上搜索了解决方案。看来Liquibase会在update命令上创建存储过程。但由于updateSQL命令会输出无效的SQL,因此会分崩离析。

我的解决方案是在changesets sql标签中添加注释。目的是使用正则表达式清理输出sql。

我正在使用的.sql文件中有一些关键字liquibase不喜欢例如DELIMITER,因此我使用<modifysql><regExpReplace>整理/清理.sql文件。 这样,.sql文件就可以被liquibase消耗掉,并且可以在update上成功运行而不会出错。

但是,我们仍然会在updateSQL上输出无效的 SQL 。为了解决这个问题,我对无效的输出.sql文件使用了另一个正则表达式搜索/替换来查找注释; -- DELIMITER $$

示例:

<changeSet id="Test1" author="author_name" context="master" runOnChange="true">
    <validCheckSum>any</validCheckSum>
    <sql><![CDATA[
        DROP PROCEDURE IF EXISTS `sp_myProcedure`;
        -- DELIMITER $$
    ]]></sql>
    <createProcedure path="yourpath/procs/sp_myProcedure.sql" relativeToChangelogFile="true" />
    <sql><![CDATA[
        -- $$ DELIMITER;
    ]]></sql>
    <modifySql>
        <regExpReplace replace="[^}]+CREATE PROCEDURE" with="CREATE PROCEDURE"/>
    </modifySql>
    <modifySql>
        <regExpReplace replace="END\s*\$\$[^}]*" with="END"/>
    </modifySql>
</changeSet>