我正在我的Sping Boot 应用程序中使用schema.sql
文件到CREATE
/DROP
表,它工作正常。
但是当我添加了更改表的过程时:
DELIMITER $$
CREATE PROCEDURE Alter_Table()
BEGIN
IF NOT EXISTS( SELECT NULL
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'test_table'
AND table_schema = 'test'
AND column_name = 'cc_test_id') THEN
alter table test_table add cc_test_id VARCHAR(128) NOT NULL;
END IF;
END $$
call Alter_Table;
我收到:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException exception.
但是,在MySQL工作台中执行此过程后,结果成功。
所以,应该有人知道这个问题的原因是什么,让我知道吗?
5条答案
按热度按时间bprjcwpo1#
下面是我发现的一个很好的解决方案,尽管它并不理想,因为您必须更改SQL脚本。
在
application.properties
文件中更改DataSource分隔符属性:然后更新
schema.sql
文件,使其如下所示:DELIMITER命令仅适用于MySQL CLI客户端和Workbench,不适用于Sping Boot 数据库初始化。删除DELIMITER命令后,Spring Boot仍将抛出异常,因为它无法理解存储过程中的
;
字符不是单独的语句,因此您必须更改数据源分隔符属性作为解决方法。7tofc5zh2#
以下是解决方法:
将您的
spring.datasource.separator
属性设置为^^^ END OF SCRIPT ^^^
,Sping Boot 会将整个schema.sql脚本作为单个语句执行。原因如下:
Sping Boot 将schema.sql脚本拆分为语句,然后将每个语句单独发送到数据库以供执行。默认情况下,脚本以分号分隔,因为这是
spring.datasource.separator
属性(per the documentation)的默认值。这会导致schema.sql被拆分,执行的第一个语句如下:这是无效的SQL,因为美元引号在语句中从不终止。
org.springframework.jdbc.datasource.init.ScriptUtils.EOF_STATEMENT_SEPARATOR
的javadoc很好地解释了我建议的解决方案是如何工作的:文件结束(EOF)SQL语句分隔符:“^^^脚本结束^^^"。
此值可以作为分隔符提供给executeSqlScript(Connection,EncodedResource,boolean,boolean,String,String,String,String),以表示SQL脚本包含没有显式语句分隔符的单个语句(可能跨越多行)。请注意,此类脚本实际上不应包含此值;它只是一个虚拟语句分隔符。
sgtfey8w3#
使用适当的分隔符
EOF_STATEMENT_SEPARATOR
自定义数据库填充器可解决此问题:3qpi33ja4#
以上答案在2022年对我来说都不管用,但它们提供了一个焦点,让我可以提出自己的解决方案。我在类似的问题下发布了我的答案,但为了完整起见,为了保存你一些额外的点击,我也在这里提供了它。
我也曾经遇到过这个问题,现在我找到了一个解决方案。实际上是3个!所以你可以选择任何一个适合你的需要。但它的关键是正确格式化的
String
,它代表了创建SP的DB脚本。我还没有弄清楚如何在一个SQL脚本/字符串中合并删除和创建SP,但我对这些解决方案很满意。仅供参考:
String
的最重要部分解决方案1:使用
JdbcTemplate
和JavaString
在格式良好的
String
sql脚本中保留尾随空格非常重要解决方案2:使用
ResourceDatabasePopulator
&ClassPathResource
将SQL脚本加载到文件中解决方案3:使用
ScriptUtils
&ClassPathResource
将SQL脚本加载到文件中create-sp_TEST_STORED_PROC.sql
脚本的内容对于溶液#1和#2,适用与第一种溶液相同的规则:
因此,下面的代码由我的
vim
设置存档,以表示空白字符我相信它在内部表现为一条线:
CREATE PROCEDURE test_stored_proc (IN pInstanceId varchar(255)) BEGIN SELECT * FROM vw_subscriptions WHERE instanceId = pInstanceId; END
个几乎完整的源代码可以在我的GitHub上找到
4zcjmb1e5#
如果您尝试为SpringBootTest加载脚本,
@Sql
和@SqlConfig
将起作用。在sql脚本中,应该删除
DELIMITER $$
语句。如下所示:如果脚本文件只包含一个
CREATE PROCEDURE
语句,则separator=EOF_STATEMENT_SEPARATOR
语句将正常。