H2数据库中用于java中测试类的自定义函数

问题描述 投票:0回答:1

我的应用程序基于 Java 和 Spring 框架以及 Oracle 数据库,在我的应用程序中我使用以下查询来获取数据。

查询:

select sub.subscriber_id
RTRIM 
( xmlagg (xmlelement (c, subsrc.source_cd || ',') order by subsrc.source_cd).extract ('//text()') 
, ',' ) AS subscribed_sourceCodes 
from DR_DBA.submodule sub, DR_DBA.submoudle_source subsrc, DR_DBA.source src 
where subsrc.subscriber_id = sub.subscriber_id 
        and subsrc.source_cd = src.source_cd 
        and sub.active_in = 'Y' 
        and src.subscribed_in = 'Y' 
group by  sub.subscriber_id;

上述查询在 SQL 开发人员和应用程序中均正常工作。

在编写集成测试类时,我们决定在内存数据库中创建H2数据库以用于测试目的。但上述查询失败并出现以下错误

错误:

Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "select sub.subscriber_id
RTRIM 
( xmlagg (xmlelement (c, subsrc.source_cd || ',') order by subsrc.source_cd).extract ('//text()') 
, ',' ) AS subscribed_sourceCodes 
from DR_DBA.submodule sub, DR_DBA.submoudle_source subsrc, DR_DBA.source src 
where subsrc.subscriber_id = sub.subscriber_id 
        and subsrc.source_cd = src.source_cd 
        and sub.active_in = 'Y' 
        and src.subscribed_in = 'Y' 
group by  sub.subscriber_id;"; expected "[, ., ::, AT, FORMAT, *, /, %, +, -, ||, NOT, IS, ILIKE, REGEXP, AND, OR, ,, )"; SQL statement:
select sub.subscriber_id
RTRIM 
( xmlagg (xmlelement (c, subsrc.source_cd || ',') order by subsrc.source_cd).extract ('//text()') 
, ',' ) AS subscribed_sourceCodes 
from DR_DBA.submodule sub, DR_DBA.submoudle_source subsrc, DR_DBA.source src 
where subsrc.subscriber_id = sub.subscriber_id 
        and subsrc.source_cd = src.source_cd 
        and sub.active_in = 'Y' 
        and src.subscribed_in = 'Y' 
group by  sub.subscriber_id;  [42001-220]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:514)
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:489)
    at org.h2.message.DbException.getSyntaxError(DbException.java:261)
    at org.h2.command.Parser.getSyntaxError(Parser.java:910)
    at org.h2.command.Parser.read(Parser.java:5793)
    at org.h2.command.Parser.readIfMore(Parser.java:1312)

鉴于我已经为 xmlagg 、 xmlelement 和 RTRIM 创建了自定义函数。 调试后,发现发生了错误,因为 "order by subsrc.source_cd).extract ('//text()') "

有什么解决办法吗?比如如何应对这种情况。鉴于此,我们无法更改查询

创建自定义函数,因为 H2 不支持以下函数

架构.sql

drop ALIAS if exists XMLAGG;
CREATE ALIAS XMLAGG as '
import java.lang.*;
@CODE
java.lang.String toDate(String s) throws Exception {
  return "";
}
'

schema1.sql

drop ALIAS if exists XMLELEMENT;
CREATE ALIAS XMLELEMENT as '
import java.lang.*;
@CODE
java.lang.String toDate(String s, String dateFormat) throws Exception {
  return "";
}
'

schema2.sql

drop ALIAS if exists RTRIM;
CREATE ALIAS RTRIM as '
import java.lang.*;
@CODE
java.lang.String toDate(String s, String dateFormat) throws Exception {
  return s;
}
'

URL:jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=ORACLE;INIT=RUNSCRIPT FROM 'classpath:./schema.sql'\;RUNSCRIPT FROM 'classpath:./schema1.sql' \;RUNSCRIPT FROM 'classpath:./schema2.sql'

java spring hibernate spring-data-jpa h2
1个回答
0
投票

使用 H2 来测试使用特定于供应商的功能的查询并不是一个好主意。当然,您可以尝试为缺少的功能定义自己的函数,但这只是您将面临的巨大问题之一。您可以尝试在 H2 测试中使用 jdbc url 中的

MODE=Oracle
以 Oracle 模式启动 H2,但这只能缓解一些问题,并且它的设计目的不是覆盖底层 Oracle 数据库的所有细节,而只是覆盖最基本的细节。

我强烈建议您使用 testcontainers 项目 for Oracle

鉴于此,我们无法更改查询

这正是 testcontainers lib 存在的原因,因为某些 SQL 查询只能由非常特定的供应商执行。该库将仅启动您拥有的 RDBMS 的 docker 进程,例如您的情况下的 Oracle,因此查询不需要更改,因为在您的测试中您使用的是轻量级 Oracle 数据库,而不是 H2。

© www.soinside.com 2019 - 2024. All rights reserved.