繁体   English   中英

Spring 启动 MySQL 存储过程数据库初始化错误

[英]Spring Boot MySQL Database Initialization Error with Stored Procedures

在 Spring Boot 应用程序中,我试图在运行集成测试之前初始化一些 MySQL 数据库表和存储过程,方法是按照文档中的建议将 schema.sql 文件放在我的资源目录中。

create table 语句有效,但 create procedure 语句抛出异常。 导致异常的示例 schema.sql 文件语句如下所示:

DROP PROCEDURE IF EXISTS `database`.FOO;
CREATE PROCEDURE `database`.FOO()

BEGIN
  SELECT * from `database`.employees;
END;

问题是; 存储过程中的字符被 Spring ScriptUtils class 解析出来,它在执行之前解析 schema.sql 文件,然后导致 MySQL 在脚本上抛出语法错误。

我查看了ScriptUtils class,但未能找到逃避;的方法。 字符与程序。 使用\\\作为转义字符也不起作用,MySQL DELIMITER命令也是如此。

有没有人能够使用带有 Spring Boot 的 schema.sql 文件创建 MySQL 存储过程? 如果可以,他们可以举个例子吗?

有关一些其他信息,以下Spring JIRA 问题解决了相同的主题,但已关闭,无法修复label。

答案非常简单。 Spring Boot 有一个 DataSource 分隔符属性,可以在 application.properties 文件中设置:

spring.datasource.separator=^;

然后在schema.sql文件中全部; 不在存储过程中的语句需要使用新的分隔符进行更新。

DROP PROCEDURE IF EXISTS `database`.FOO;
CREATE PROCEDURE `database`.FOO()

BEGIN
  SELECT * from `database`.employees;
END ^;

添加到@Andrews 答案:

当使用不是由 Spring Boot 自动创建的自定义dataSource ,可能会发生没有使用spring.datasource.separator属性的情况。 在这种情况下,分隔符不会转发到Populator 在这种情况下,它可以直接在数据源初始化中设置。 例如,假设dataSource在其他地方定义,则可以在特殊更新配置文件中使用以下内容:

<jdbc:initialize-database data-source="dataSource" enabled="${initDatabase:false}" separator="^;">
    <jdbc:script location="${update.schema.script}" />
</jdbc:initialize-database>

或者,当显式声明填充器时:

<bean id="dbPopulator" class="org.springframework.jdbc.datasource.init.ResourceDatabasePopulator">
    <property name="separator" value="^;"/>
    <property name="scripts">
        <list>
            <value>${update.schema.script}</value>
        </list>
    </property>
</bean>
<bean id="initDatabase" class="org.springframework.jdbc.datasource.init.DataSourceInitializer">
    <property name="dataSource">
        <ref bean="dataSource"/>
    </property>
    <property name="databasePopulator">
        <ref bean="dbPopulator"/>
    </property>
    <!-- The same can be done for the cleaner: -->
    <!-- <property name="databaseCleaner"><ref bean="dbCleanup"/></property> -->
</bean>

如果有人像我一样使用 spring-boot + testcontainers 进入这个线程,可以省略分隔符,因为 testcontainers 的解析器知道程序 synthax(尽管仍然不适用于 MS-SQL)。 所以原始脚本将起作用:

DROP PROCEDURE IF EXISTS `database`.FOO;
CREATE PROCEDURE `database`.FOO()

BEGIN
  SELECT * from `database`.employees;
END;

如果使用注释进行测试,那么您可以执行以下操作:

@Sql(
        scripts = "/myTestSQL.sql",
        config = @SqlConfig(separator = "^;")
)
@Test
void mySQLTest() {
    // my test logic
}

鉴于myTestSQL.sql存储在测试resources文件夹中。 此外,只有不同的过程或查询才能用^; , 过程中的内容仍然应该用;分开 ,就像在https://stackoverflow.com/a/35871322/2092109回答

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM