2

I have a couple of stored procedures that I want to execute as initial setup. So What I have done, placed that stored procedure in data.sql and set the jpa.hibernate.ddl-auto=create.

But on startup of my springboot application, the application is failing with com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException. It means, it is not able to understand the syntax of that procedure, however the same procedure can be executed manually on sql sheet without any problem. So how can I execute it via data.sql

data.sql -

DELIMITER $$

CREATE PROCEDURE `GetStocks`(int_stockcode varchar(20))
BEGIN
  DECLARE stock_name VARCHAR(100);
  SELECT name FROM stock where stock_code = int_stockcode INTO stock_name;
END $$

DELIMITER ;

error-

Caused by: org.springframework.jdbc.datasource.init.ScriptStatementFailedException:

Failed to execute SQL script statement #29 of class path resource [default-data.sql]: DELIMITER $$ CREATE PROCEDURE GetStocks(int_stockcode varchar(20)) BEGIN SELECT * FROM stock where stock_code = int_stockcode; nested exception is 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 $$ CREATE PROCEDURE GetStocks(int_stockcode varchar(20)) BEGIN SELEC' at line 1

at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:491) at org.springframework.jdbc.datasource.init.ResourceDatabasePopulator.populate(ResourceDatabasePopulator.java:238) at org.springframework.jdbc.datasource.init.DatabasePopulatorUtils.execute(DatabasePopulatorUtils.java:48) at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.runScripts(DataSourceInitializer.java:192) at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.runDataScripts(DataSourceInitializer.java:128) at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.onApplicationEvent(DataSourceInitializer.java:118) at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.onApplicationEvent(DataSourceInitializer.java:51) at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:167) at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:393) at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:347) at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher.publishEventIfRequired(DataSourceInitializedPublisher.java:77) at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher.postProcessAfterInitialization(DataSourceInitializedPublisher.java:68) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:423) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(AbstractAutowireCapableBeanFactory.java:1775) at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:113) ... 75 common frames omitted 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 $$ CREATE PROCEDURE GetStocks(int_stockcode varchar(20)) BEGIN SELEC' at line 1 at sun.reflect.GeneratedConstructorAccessor71.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) at com.mysql.jdbc.Util.getInstance(Util.java:408) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:943) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2680) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2486) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2444) at com.mysql.jdbc.StatementImpl.executeInternal(StatementImpl.java:845) at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:745) at sun.reflect.GeneratedMethodAccessor27.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114) at com.sun.proxy.$Proxy106.execute(Unknown Source) at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:470) ... 90 common frames omitted

8
  • Can you please add the whole stacktrace? Commented Jan 9, 2020 at 8:21
  • Edited question to show whole stacktrace Commented Jan 9, 2020 at 8:34
  • Seems the driver is not respecting the delimiter.You can try looking at this stackoverflow.com/questions/56483637/… and this stackoverflow.com/questions/56989767/… Commented Jan 9, 2020 at 10:05
  • Sorry that answer in the thread does not seem working Commented Jan 9, 2020 at 10:38
  • Could you post the error what you are getting after applying that fix? Commented Jan 9, 2020 at 12:37

1 Answer 1

2

For loading and creating the database objects it is better to stick to liquibase or flyway. Using the following code it is possible to load the stored procedure.

Used a controller to load the stored procedure but it can be a simple class or can be configured via an event listener.

@RestController
public class SqlLoaderController {

    @Autowired
    DataSource dataSource;

    @GetMapping("/load")
    public void loadScript() throws Exception
    {

        ResourceDatabasePopulator resourceDatabasePopulator=new ResourceDatabasePopulator();
        resourceDatabasePopulator.setSeparator("DELIMITER");
        InputStream is= new ClassPathResource("sql.txt").getInputStream();
        resourceDatabasePopulator.addScript(new InputStreamResource(is));
        resourceDatabasePopulator.execute(dataSource);

    }
}

The DELIMITER is used to distinguish between start and end of two stored procedure or database objects.The sql.txt file

CREATE PROCEDURE GetStocks(int_stockcode varchar(20))
BEGIN
  DECLARE stock_name VARCHAR(100);
  SELECT 1 FROM dual;
END;

DELIMITER

CREATE PROCEDURE GetStocks1(int_stockcode varchar(20))
BEGIN
  DECLARE stock_name VARCHAR(100);
  SELECT 1 FROM dual;
END;
DELIMITER
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.