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

Hsqldb存储过程

洪弘亮
2023-03-14

我试图在我的内存Hsqldb数据库中设置一个存储过程,用于测试目的。我正在使用的存储过程是在MySql中开发的,所以我想用HSqlDb来设置它,以适应我的测试包

我试图创建一个简化版本的程序,但还没有乐趣。

程序是

     CREATE PROCEDURE p_recordTaskExecution(IN userTaskId INT, IN isSuccess BOOLEAN, IN statusMessage VARCHAR(2000), IN operationsPerformed INT, INOUT procedureStatus BOOLEAN) 
  BEGIN ATOMIC
  IF userTaskId = 1 Then
        set procedureStatus = true;

  ELSE
    set procedureStatus = false;

  END IF;

  END;

我在运行测试时遇到的错误如下

Caused by: org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement at line 3 of resource class path resource [databaseTesting/inMemory/createInMemoryDatabase.sql]: CREATE PROCEDURE p_recordTaskExecution(IN userTaskId INT, IN isSuccess BOOLEAN, IN statusMessage VARCHAR(2000), IN operationsPerformed INT, INOUT procedureStatus BOOLEAN) BEGIN ATOMIC if userTaskId = 1 Then set procedureStatus = true; nested exception is java.sql.SQLSyntaxErrorException: unexpected end of statement:  required: ;
    at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:475)
    at org.springframework.jdbc.datasource.init.ResourceDatabasePopulator.populate(ResourceDatabasePopulator.java:229)
    at org.springframework.jdbc.datasource.init.CompositeDatabasePopulator.populate(CompositeDatabasePopulator.java:60)
    at org.springframework.jdbc.datasource.init.DatabasePopulatorUtils.execute(DatabasePopulatorUtils.java:48)
    at org.springframework.jdbc.datasource.init.DataSourceInitializer.execute(DataSourceInitializer.java:108)
    at org.springframework.jdbc.datasource.init.DataSourceInitializer.afterPropertiesSet(DataSourceInitializer.java:93)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1625)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1562)
    ... 40 more
Caused by: java.sql.SQLSyntaxErrorException: unexpected end of statement:  required: ;
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source)
    at org.hsqldb.jdbc.JDBCStatement.execute(Unknown Source)
    at com.jolbox.bonecp.StatementHandle.execute(StatementHandle.java:254)
    at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:460)
    ... 47 more
Caused by: org.hsqldb.HsqlException: unexpected end of statement:  required: ;

共有3个答案

苏俊友
2023-03-14

END IFEND之后不需要分号。错误信息有点误导。

编辑您可能还需要在创建过程中将分号加倍 文本,因为Spring本身认为分号也是语句分隔符。

上官思博
2023-03-14

此配置与@Damo指定的配置相同,但避免使用XML配置。

ScriptUtils.executeSqlScript(ds.getConnection(),  new EncodedResource(
                new InputStreamResource(getClass().getClassLoader().getSystemResourceAsStream("procs.sql"))
                ), false, false, "--", "/;", "--", "--");

这是方法签名:

void org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(Connection connection, EncodedResource resource, boolean continueOnError, boolean ignoreFailedDrops, String commentPrefix, String separator, String blockCommentStartDelimiter, String blockCommentEndDelimiter) throws ScriptException
桑宇
2023-03-14

我终于得到了答案,感谢下面的stackoverflow链接HSQL创建过程语法似乎不匹配留档

为了完整,这就是我所做的

>

  • 我将我的hsqldb sql代码分为两个文件。一个是创建表和数据语法,另一个是存储过程

    加载此文件时,我能够指定要使用的分隔符

    <jdbc:initialize-database data-source="mctDBDataSource" ignore-failures="DROPS" >
        <jdbc:script location="classpath:databaseTesting/inMemory/createInMemoryDatabase.sql" separator=";"/>
        <jdbc:script location="classpath:databaseTesting/inMemory/createInMemoryDatabaseProcedures.sql" separator="/;"/>
    </jdbc:initialize-database>
    

    如前所述,Spring处理分号;作为语句的结尾,因此我可以为存储的procs文件指定不同的分隔符

    更新了我的存储过程以使用新的分离器,现在一切按预期工作

    CREATE PROCEDURE p_recordTaskExecution(IN userTaskId BIGINT, IN isSuccess BOOLEAN, IN statusMessage VARCHAR(2000), IN operationsPerformed BIGINT, INOUT procedureStatus BOOLEAN) 
    BEGIN ATOMIC
        IF userTaskId = 1 Then
            SET procedureStatus = true; 
        ELSE
            SET procedureStatus = false;
        END IF;
    END;
    /;
    

  •  类似资料:
    • 是否可以在HSQLDB存储过程结束之前返回? 我试过: 这不能编译。用或代替。

    • 是否可以在HSQLDB中创建递归存储过程? 我编写了以下一个来更新一个记录,并递归地更新所有父记录: 但我得到了以下错误: 在HyperSQL用户指南中,我找到了一些信息(请参阅HyperSQL用户指南中的递归例程),但它似乎只支持函数。 提前感谢您的支持。

    • 在HSQLDB中,我试图创建一个存储过程,在更新数据库后执行提交。 类似:创建过程MY_PROC(p_id整数)修改SQL数据开始原子更新提交结束 创建此过程时,通过调用JDBC Statement.execute()方法,我得到了一个错误:SQLSynTaxErrorExctive:意外令牌:COMMIT必需:END 如果没有COMMIT语句,则过程将被正确编译。 知道我做错了什么吗?

    • 我试图写一个存储过程。通过SQL浏览器创建它很顺利,但是当我把它保存在SQL文件中并通过SQLTool加载它时,它失败了 我收到以下错误 调用SqlTool。objectMain(sqlToolParams); 在哪里 我需要帮助纠正语法。 我试图从他那里得到线索http://hsqldb.org/doc/2.0/util-guide/sqltool-chapt.html#sqltool_raw-

    • 我有一个基于spring的java web应用程序,它使用HSQLDB dbms后端在事务中插入大量记录。为了减少为要插入的记录生成主键的往返次数,我想创建一个存储过程,生成主键,在插入之前将其用作标识符。因此,我用以下代码创建了一个存储过程: 有一个序列GENERATE_PKS_SEQ,用于为要插入的记录生成唯一标识符。此存储过程需要一个数字输入(NUMBEROFIDS)来定义要生成的密钥数。

    • 数据访问层支持存储过程调用,调用数据库存储过程使用下面的方法: $resultSet = Db::query('call procedure_name'); foreach ($resultSet as $result) { } 存储过程返回的是一个数据集,如果你的存储过程不需要返回任何的数据,那么也可以使用execute方法: Db::execute('call procedure_name'