2015-11-19 602 views
1

我正在使用Gradle 2.7,MySQL 5.5.46和Liquibase-Gradle 1.1.1插件。我有一个存储过程看起来像...如何使用Liquibase将存储过程导入到MySQL中?

DELIMITER // 

DROP PROCEDURE IF EXISTS MyProc; 

CREATE PROCEDURE MyProc(
IN param1 VARCHAR(25), 
IN param2 VARCHAR(5), 
OUT outParam VARCHAR(2500)) 

BEGIN 
… 
END // 

我能够导入这个文件很好的MySQL命令行。然而,当我创建这个Liquibase变更...

<changeSet id="create_my_stored_proc" author="davea"> 
    <sqlFile path="src/main/resources/scripts/my_stored_proc.sql" stripComments="true"/> 
</changeSet> 

,并运行它,我得到的错误

Caused by: liquibase.exception.DatabaseException: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 'DELIMITER // 

DROP PROCEDURE IF EXISTS MyProc’ at line 1 
    at liquibase.executor.jvm.JdbcExecutor$ExecuteStatementCallback.doInStatement(JdbcExecutor.java:316) 
    at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:55) 
    at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:122) 
    at liquibase.database.AbstractJdbcDatabase.execute(AbstractJdbcDatabase.java:1227) 
    at liquibase.database.AbstractJdbcDatabase.executeStatements(AbstractJdbcDatabase.java:1210) 
    at liquibase.changelog.ChangeSet.execute(ChangeSet.java:550) 
    ... 126 more 
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 'DELIMITER // 

DROP PROCEDURE IF EXISTS MyProc’ at line 1 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422) 
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:400) 
    at com.mysql.jdbc.Util.getInstance(Util.java:383) 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:980) 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3847) 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3783) 
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2447) 
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2594) 
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2541) 
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2499) 
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:844) 
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:748) 
    at liquibase.executor.jvm.JdbcExecutor$ExecuteStatementCallback.doInStatement(JdbcExecutor.java:314) 

什么我需要做的,纠正这一错误?

编辑:我删除每个答案的“分隔符”行让我的文件看起来像......

DROP PROCEDURE IF EXISTS MyProd; 

CREATE PROCEDURE MyProc(
IN param1 VARCHAR(25), 
IN param2 VARCHAR(5), 
OUT outParam VARCHAR(2500)) 

BEGIN 
… 
END // 

然而,在运行变更我得到这个错误...

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 'CREATE PROCEDURE MyProc(
IN param1 VARCHAR(25), 
IN param2 VAR' at line 3 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422) 
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:400) 
    at com.mysql.jdbc.Util.getInstance(Util.java:383) 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:980) 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3847) 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3783) 
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2447) 
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2594) 
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2541) 
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2499) 
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:844) 
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:748) 
    at liquibase.executor.jvm.JdbcExecutor$ExecuteStatementCallback.doInStatement(JdbcExecutor.java:314) 
    ... 131 more 

回答

2

相反与在文件中指定分隔符相比,您必须在更改中指定它。要做到这一点,请从SQL文件,其中包含DELIMITER行,然后改变变更,所以它看起来是这样的:

<changeSet id="create_my_stored_proc" author="davea"> 
    <sqlFile endDelimiter="//" path="src/main/resources/scripts/my_stored_proc.sql" stripComments="true" /> 
</changeSet> 
+0

感谢您的答复保持在SQLFILE这一说法。我删除了DELIMTER行,根据您的建议并更新了适当的更改集,但仍然收到错误(包含在我的问题中)。请注意,使用DELIMITER参数,我可以通过MySQL命令行导入文件。 – Dave

+0

K,删除“DROP PROCEDURE”行也允许正常运行。 – Dave

+0

MySQL命令行允许的命令与通过JDBC驱动程序发送命令时允许的命令不同,并且并不总是清楚在哪里允许哪些命令。其他数据库也是如此。使用Oracle sqlplus命令行可以执行的操作与通过驱动程序运行普通SQL时允许执行的操作不同。 – SteveDonie

1

对于LiquiBase创建过程需要使用XML创建过程中,它会解决你的问题。也编译它并检查是否没有错误。

<changeSet id="create_my_stored_proc" author="davea"> 
<createProcedure path="src/main/resources/scripts/my_stored_proc.sql"/> 
<sql>alter procedure MyProc compile;</sql> 
<sql>call MyProc();</sql> 
<changeSet id="create_my_stored_proc" author="davea"> 
0

线

DROP PROCEDURE IF EXISTS MyProc; 

与您的编辑过的文件生成的错误,因为它具有默认定界符(;)结束,而分隔符已被更改为//。你可以使用变更后的分隔符//,即:

DROP PROCEDURE IF EXISTS MyProc //