如何使用 Liquibase 将存储过程导入 MySQL?
How do I use Liquibase to import a stored procedure into MySQL?
我正在使用 Gradle 2.7、MySQL 5.5.46 和 Liquibase-Gradle 1.1.1 插件。我有一个包含存储过程的文件,看起来像……
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)
我需要做什么来纠正这个错误?
编辑: 我根据答案删除了“DELIMITER”行,使我的文件看起来像……
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
您不必在文件中指定分隔符,而必须在更改本身中指定它。为此,从 sql 文件中删除包含 DELIMITER
的行,然后更改变更集,使其看起来像这样:
<changeSet id="create_my_stored_proc" author="davea">
<sqlFile endDelimiter="//" path="src/main/resources/scripts/my_stored_proc.sql" stripComments="true" />
</changeSet>
对于 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">
行
DROP PROCEDURE IF EXISTS MyProc;
您编辑的文件产生错误,因为它以默认分隔符结尾(;),而分隔符已更改为 //.您可以使用更改后的定界符 // 将此语句保留在 sqlFile 中,即:
DROP PROCEDURE IF EXISTS MyProc //
我正在使用 Gradle 2.7、MySQL 5.5.46 和 Liquibase-Gradle 1.1.1 插件。我有一个包含存储过程的文件,看起来像……
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)
我需要做什么来纠正这个错误?
编辑: 我根据答案删除了“DELIMITER”行,使我的文件看起来像……
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
您不必在文件中指定分隔符,而必须在更改本身中指定它。为此,从 sql 文件中删除包含 DELIMITER
的行,然后更改变更集,使其看起来像这样:
<changeSet id="create_my_stored_proc" author="davea">
<sqlFile endDelimiter="//" path="src/main/resources/scripts/my_stored_proc.sql" stripComments="true" />
</changeSet>
对于 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">
行
DROP PROCEDURE IF EXISTS MyProc;
您编辑的文件产生错误,因为它以默认分隔符结尾(;),而分隔符已更改为 //.您可以使用更改后的定界符 // 将此语句保留在 sqlFile 中,即:
DROP PROCEDURE IF EXISTS MyProc //