簡體   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