Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use Liquibase to import a stored procedure into MySQL?

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
like image 626
Dave Avatar asked Nov 19 '15 17:11

Dave


People also ask

How should stored procedures be managed Liquibase?

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"?

How do I create a procedure in Liquibase?

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.

How Liquibase works?

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.

How do I run a SQL file in Liquibase?

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.


1 Answers

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>
like image 62
SteveDonie Avatar answered Oct 21 '22 08:10

SteveDonie