当前位置: 首页 > 知识库问答 >
问题:

Spring JDBC在运行SQL脚本时无法处理DECLARE语句

饶承宣
2023-03-14

为了复制此场景,我编写了以下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;

我已经使用IntelliJ运行了这个脚本,它按预期工作。

但是,当我将脚本放入@SQL注释中时,我遇到了以下错误:

org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of class path resource [sql/setUp.sql]: DECLARE id integer := 1; nested exception is java.sql.SQLException: ORA-06550: line 1, column 23:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:

   * & = - + ; < / > at in is mod remainder not rem
   <an exponent (**)> <> or != or ~= >= <= <> and or like like2
   like4 likec between || multiset member submultiset
BEGIN
    INSERT INTO USER (ID, FIRST_NAME, LAST_NAME, AGE)
    VALUES (1, 'John', 'Smith', 32);
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语句)是可行的。

那么Spring JDBC不支持begin/end块吗?pretest@sql注释是否有我不知道的限制?还是我错过了一些明显的痛苦?

共有1个答案

包唯
2023-03-14

感谢@MarkRotteveel的建议,我找到了这个问题的解决方案。

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
}

请注意,我必须分离清理和设置脚本,因为更改分隔符可能会破坏一些以前工作的脚本。

 类似资料:
  • 我必须在IE 10浏览器上运行Selenium测试。为了运行以下脚本,我执行了以下操作: > 从这里下载了IEDriverServer(64位,因为我的机器是64位) 将该(. exe)文件放在“C://驱动程序”文件夹中 设置路径'C://驱动程序'在环境变量 运行脚本 运行 aboe 脚本会导致以下错误: 同样的脚本在Chrome和Firefox浏览器上运行良好。请帮助我理解我做错了什么。

  • 我在这个Batch脚本中有一个语法错误,但我不知道它是从哪里来的。我是批处理新手,所以我很难弄清楚这一点。我感觉这与语句有关,但我不确定。 我得到的当前错误是: 该命令的语法不正确。

  • 问题内容: 我正在使用Oracle 11g,正在通过Java代码执行Oraclesql脚本。我的SQL脚本可能包含SQL语句(DDL或DML)或PL /SQL块,因此我不想解析Java代码中的脚本,但使用此解决方案立即执行了完整的脚本。以下是示例代码,其中包含SQLExec类。 此解决方案在大多数情况下都有效,除了如果sql脚本包含它会失败,并显示 java.sql.SQLSyntaxErrorE

  • 我正在使用Oracle 11g,我正在通过java代码执行Oracle sql脚本。我的SQL脚本可能包含SQL语句(DDL或DML)或PL/SQL块,所以我不想在我的java代码中解析脚本,而是使用此解决方案一次执行完整的脚本。下面是示例代码,其中SQLExec类位于ant jar中。 此解决方案适用于大多数情况,但如果sql脚本包含,则会因java.sql.SQLSyntaxErrorExce

  • 我想在我的Parallela板启动时运行一个bash脚本,它有Ubuntu。我搜索了SO,在这里找到了说明: 在linux ubuntu下启动时自动运行程序 在Linux上启动时以编程方式运行 我的bash脚本是test。sh,只有一行: 1) 我尝试的第一种方法是添加到脚本的aboslute路径: 2) 我尝试的第二种方法是遵循上面公认的答案。 在这两种情况下,脚本都是在引导后执行的,并且有一个

  • 我使用Inno Setup#定义指令来定义安装程序中有关软件包的所有信息,然后使用其他指令来提取该字符串的部分。例如,使用以下命令,将返回05414。 我在脚本和代码中使用这种方法,而且效果很好。然而,我遇到了一种情况,即通过编程生成字符串会很方便,而且我很难让它正常工作。例如,我想做以下事情。 的参数是正确的,但我收到一个编译器错误消息 [ISPP]格式“%”没有参数。 它似乎不喜欢行字符串中的