Java SpringJDBC在运行SQL脚本时无法处理DECLARE语句
我有一个Spring CRUD应用程序,带有一个Oracle SQL数据库 我有几个集成测试,并使用Java SpringJDBC在运行SQL脚本时无法处理DECLARE语句,java,spring,oracle,jdbc,plsql,Java,Spring,Oracle,Jdbc,Plsql,我有一个Spring CRUD应用程序,带有一个Oracle SQL数据库 我有几个集成测试,并使用@Sql注释来运行.Sql文件,这些文件在运行测试之前将数据库置于所需的状态。到目前为止,我的任何.sql脚本都没有问题,尽管它们都是非常简单的INSERT和DROP语句 我现在尝试设置一个场景,其中数据库在一个特定表中保存数千条记录。我不在乎内容,只在乎记录的数量 为了复制此场景,我编写了以下SQL脚本: DECLARE id integer := 1; BEGIN WHILE
@Sql
注释来运行.Sql文件,这些文件在运行测试之前将数据库置于所需的状态。到目前为止,我的任何.sql脚本都没有问题,尽管它们都是非常简单的INSERT和DROP语句
我现在尝试设置一个场景,其中数据库在一个特定表中保存数千条记录。我不在乎内容,只在乎记录的数量
为了复制此场景,我编写了以下SQL脚本:
DECLARE
id integer := 1;
BEGIN
WHILE id <= 3000
LOOP
INSERT INTO USER (ID, FIRST_NAME, LAST_NAME, AGE)
VALUES (id, 'John', 'Smith', 32);
id := id + 1;
END LOOP;
END;
这就产生了以下错误,这就更加没有意义了:
org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of class path resource [sql/test.sql]: BEGIN INSERT INTO USER (ID, FIRST_NAME, LAST_NAME, AGE) VALUES (1, 'John', 'Smith', 32); nested exception is java.sql.SQLException: ORA-06550: line 1, column 87:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
;
最有趣的是,删除BEGIN和END语句(只保留INSERT INTO语句)是有效的
那么SpringJDBC不支持开始/结束块吗?我不知道对pre-test@Sql注释有什么限制吗?还是我错过了一些显而易见的痛苦?多亏@markrottveel的建议,我找到了解决这个问题的方法 JDBC确实在运行脚本的每一行,就好像它是一条单独的语句,这与语句块不兼容。这是因为
分隔符设置为默认情况下,代码>符号,导致JDBC处理以结尾的每个代码块代码>好像它是一个单独的脚本。我将此分隔符设置为EOF符号,这导致JDBC将整个文件视为单个脚本
我最初的测试代码如下所示:
@Sql(scripts = {"sql/cleanup.sql", "sql/setUp.sql"})
public void testWithThousandsOfRecords() {
// do tests
}
@Sql(scripts = "sql/cleanup.sql")
@Sql(scripts = "sql/setUp.sql", config = @SqlConfig(separator = ScriptUtils.EOF_STATEMENT_SEPARATOR))
public void testWithThousandsOfRecords() {
// do tests
}
我的测试代码现在如下所示:
@Sql(scripts = {"sql/cleanup.sql", "sql/setUp.sql"})
public void testWithThousandsOfRecords() {
// do tests
}
@Sql(scripts = "sql/cleanup.sql")
@Sql(scripts = "sql/setUp.sql", config = @SqlConfig(separator = ScriptUtils.EOF_STATEMENT_SEPARATOR))
public void testWithThousandsOfRecords() {
// do tests
}
请注意,我必须将清理脚本和设置脚本分开,因为更改分隔符可能会破坏以前工作过的一些脚本。请提供一个详细的说明。问题似乎是,无论你在做什么,都是在上分裂
发送单个语句(因为JDBC本身只支持单个语句执行)。要执行这样的脚本,通常需要以某种方式切换或禁用语句终止符,以便能够发送整个内容。这意味着您可能需要微调@Sql
的@SqlConfig
(例如分隔符的值
)。@markrottveel:Oracle JDBC驱动程序支持运行匿名PL/Sql块,因为它实际上是一条语句。可能是春天在试图分割看起来像是多重的东西statements@a_horse_with_no_name是的,@Sql
的作用是在上拆分代码>。就弹簧而言,在每次之后代码>它遇到一个新的语句开始。不是答案,因为我不确定它是否正确,但您可以尝试在结束后添加另一行代码>语句,在第一列中只有一个/
字符。@markrottveel感谢您的建议,我找到了一个解决方案。非常感谢!如果需要在脚本中有多个语句,请考虑使用自定义语句终止符(例如,<代码> < <代码> >代替<代码>;<代码> >,而不是使用<代码> EFOESTATEMENTROSETION/COMPUT>。然后,您可以使用#
结束语句,同时可以继续使用。