HSQLDB带日期输入参数的存储过程调用异常排查请求
解决HSQLDB存储过程调用抛出[42561]异常的问题
看起来你在HSQLDB里模拟MSSQL存储过程时踩了个小坑,[42561]这个错误码在HSQLDB里通常指向参数不匹配、语法格式错误或者存储过程定义与调用的兼容性问题。结合你的代码,我整理了几个关键的修复点:
1. 修正存储过程的定义细节
你的存储过程虽然声明了参数,但没有在查询中使用(如果是测试阶段的占位写法也没问题),不过HSQLDB对动态结果集的游标声明有一些细节要求,同时要确保schemamap已存在:
-- 先确保schema存在(如果还没创建的话) CREATE SCHEMA IF NOT EXISTS map; CREATE PROCEDURE map.Get1(IN packageName varchar(100), IN downloadDate DATE) READS SQL DATA DYNAMIC RESULT SETS 1 BEGIN ATOMIC DECLARE result CURSOR WITH RETURN FOR SELECT * FROM map.tvschedule -- 后续测试需要用到参数的话,加上条件,比如: -- WHERE package_name = packageName AND download_date = downloadDate FOR READ ONLY; OPEN result; END;
注意:如果你的tvschedule表中有和参数同名的字段(比如packageName),最好给参数改个名字(比如p_packageName),避免HSQLDB解析时混淆。
2. 规范存储过程的调用语法
HSQLDB调用存储过程时,日期参数的格式很容易踩坑,而且schema的调用格式要准确,正确的调用语句应该是:
CALL map.Get1('Genre', DATE '2018-03-10');
或者如果你的客户端支持隐式类型转换,也可以这么写,但显式加上DATE前缀能避免大部分类型不匹配的错误:
CALL map.GET1('Genre', '2018-03-10');
3. Java代码调用的注意事项
如果是在Java里通过JDBC调用,要确保用CallableStatement的标准格式,并且参数类型匹配:
String callSql = "{CALL map.Get1(?, ?)}"; try (CallableStatement cs = connection.prepareCall(callSql)) { cs.setString(1, "Genre"); cs.setDate(2, java.sql.Date.valueOf("2018-03-10")); try (ResultSet rs = cs.executeQuery()) { // 处理结果集的逻辑 while (rs.next()) { // 读取字段 } } } catch (SQLException e) { e.printStackTrace(); }
为什么会出现[42561]错误?
这个错误对应的是HSQLDB的SQL_ERROR_CODE_42561,常见诱因包括:
- 调用时参数的数量、类型和存储过程定义不匹配;
- 存储过程内部的游标声明或语法有误;
- 日期参数没有被正确解析为DATE类型;
- schema或对象名的大小写不匹配(HSQLDB默认对标识符大小写敏感,除非你配置了兼容模式比如
sql.syntax_ora=true)。
内容的提问来源于stack exchange,提问作者Александр Шаповалов
相关产品推荐
相关产品推荐

