这是this post的后续帖子。我正在编写一个由h2数据库支持的会计系统。帐户树存储在ACCOUNTS表中,PARENT_ID列存储树中的链接。
要获取树中给定节点的路径,我有以下存储过程:
public static Long[] getAncestorPKs(Long id)
其作用是生成一个整数数组,它是给定节点和树根之间的PARENT_ID值。让我们想象它是这样定义的(因为我试过这个并且我得到了同样的错误):
public static Long[] getAncestorPKs(Long id)
{
return new Long[]{new Long(1), new Long(2), new Long(3)};
}
它已在数据库中正确注册,我可以在SQL查询中调用它。我的问题是h2似乎无法处理返回值:如果我这样使用它:
SELECT ID FROM ACCOUNTS WHERE ID IN (ANCESTOR_PKS(5))
然后我收到以下错误:
Data conversion error converting "(1, 2, 3)"; SQL statement:
SELECT ID FROM ACCOUNTS WHERE ID IN (ANCESTOR_PKS(5)) [22018-167]
相反,如果我将以下内容发送到数据库:
SELECT ID FROM ACCOUNTS WHERE ID IN (1, 2, 3)
我得到一个包含三行的结果集,包含三个整数(正是我期望的那样)。
我真的看不出这里有什么问题!我将返回一个Longs数组,用于与包含BIGINTS的列进行比较。为什么h2拒绝转换这个数组?我已经尝试将返回值设置为Object [],因为h2文档并不完全清楚返回端和呼叫端是否需要它,但这根本没有区别。我只是把头撞在一堵砖墙上。这不是火箭科学!当然有人之前写过类似的代码吗?
非常感谢,在我发疯之前!
答案 0 :(得分:0)
如果方法返回一个对象数组,那么对于数据库,这是数据类型ARRAY的一个值。而不是一个有3行的表。但是,当然您不在表中使用数据类型ARRAY,而是使用INT或BIGINT。所以你的查询不正确。
方法需要返回ResultSet,或者需要将数组值转换为表。为此,您可以使用函数TABLE(..)
,如下所示:
select x from table(x bigint = getAncestorPKs(1));
所以你能做的是:
drop table accounts;
create table accounts(id int);
insert into accounts values(1), (2), (10), (20);
drop alias getAncestorPKs;
create alias getAncestorPKs as 'Long[] getAncestorPKs(Long id) {
return new Long[]{new Long(1), new Long(2), new Long(3)};
}';
select * from accounts where id in
(select x from table(x bigint = getAncestorPKs(1)));