I’m using Gradle 2.7, MySQL 5.5.46 and the Liquibase-Gradle 1.1.1 plugin. I have a file with a stored procedure that looks like …
DELIMITER //
DROP PROCEDURE IF EXISTS MyProc;
CREATE PROCEDURE MyProc(
IN param1 VARCHAR(25),
IN param2 VARCHAR(5),
OUT outParam VARCHAR(2500))
BEGIN
…
END //
I’m able to import this file fine on a MySQL command line. However, when I create this Liquibase changeset …
<changeSet id="create_my_stored_proc" author="davea">
<sqlFile path="src/main/resources/scripts/my_stored_proc.sql" stripComments="true"/>
</changeSet>
And run it, I get the error
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)
What do I need to do to correct this error?
Edit: I removed the “DELIMITER” line per the answer making my file look like …
DROP PROCEDURE IF EXISTS MyProd;
CREATE PROCEDURE MyProc(
IN param1 VARCHAR(25),
IN param2 VARCHAR(5),
OUT outParam VARCHAR(2500))
BEGIN
…
END //
However, upon running the changeset I get this error …
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
Managing Stored Procedures: Try to maintain separate changelog for Stored Procedures and use runOnChange=”true”. This flag forces LiquiBase to check if the changeset was modified. If so, liquibase executes the change again. What do they mean by "maintain separate changelog for stored procedures"?
Often times it is best to use the CREATE OR REPLACE syntax along with setting runOnChange='true' on the enclosing changeset tag. That way if you need to make a change to your procedure, you can change your existing code rather than creating a new REPLACE PROCEDURE call.
Liquibase allows you to specify the database change you want using SQL or several different database-agnostic formats, including XML, YAML, and JSON. Developers can abstract the database code to make it extremely easy to push out changes to different database types.
Running the execute-sql command To run the execute-sql command, specify the following parameters in the Liquibase properties file, environment variables, or the command prompt while running the command: URL, driver [optional], and user authentication information such as username and password.
Rather than specifying the delimiter in the file, you have to specify it in the change itself. To do that, remove the line containing DELIMITER
from the sql file, and then alter the changeset so it looks like this:
<changeSet id="create_my_stored_proc" author="davea">
<sqlFile endDelimiter="//" path="src/main/resources/scripts/my_stored_proc.sql" stripComments="true" />
</changeSet>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With