1

这是这篇文章的后续文章。我正在编写一个由 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)

我得到一个包含 3 行的结果集,其中包含三个整数(正是我所期望的)。

我真的看不出这里有什么问题!我正在返回一个 Long 数组,用于与包含 BIGITS 的列进行比较。为什么 h2 拒绝转换这个数组?我尝试将返回值设为 Object[],因为 h2 文档并不完全清楚返回端和调用端是否需要这样做,但这根本没有区别。我只是在这里用头撞砖墙。这不是火箭科学!肯定有人以前写过类似的代码吗?

非常感谢,在我发疯之前!

4

1 回答 1

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)));
于 2012-07-26T17:09:03.003 回答