1

我正在将存储过程代码从 Oracle 迁移到 DB2,我需要找到一种方法来测试数组成员资格(Oracle 有一个MEMBER OF运算符)。

除其他外,存储过程使用一组用户(通过 JDBC 作为 Java 代码的参数接收)。我想找到在该数组中进行成员资格测试的最有效方法。使用 Oracle,我会这样做:

FOR r IN (SELECT * FROM acls WHERE acls.id = curid) LOOP
  IF r.user MEMBER OF users THEN
    RETURN 1;
  END IF;
END LOOP;

MEMBER OF但是我在 DB2 中找不到等效项:

FOR r AS SELECT * FROM acls WHERE acls.id = curid DO
  IF r.user ????? users THEN
    RETURN 1;
  END IF;
END FOR;

我看到两种选择:

  1. 对所有数组元素执行另一个内部循环以“手动”进行测试。
  2. 不要使用数组,而是使用单个字符串并使用LIKE基于 - 的模式匹配。

有没有更好的办法?请记住,数组来自外部代码,不能作为我可以JOIN或任何相关的表传递。

4

1 回答 1

0

您可以使用关联数组(在 DB2 9.7+ 中可用)和array_exists谓词来做到这一点。我不确定这是否适用于传递到程序中的内容。

但是,我发现array_exists速度很慢。您使用光标循环的一般设计也将非常慢。

如果性能是一个问题,您可能最好改为执行以下操作之一:

  • 将用户数组放入过程中的临时表中,然后join对该表执行正常操作以查找匹配的记录。
  • 使用动态 SQL 构造查询(例如在in子句中。

这是您可以使用动态 SQL 执行的操作的示例。对于此解决方案,让 Java 向您发送一个字符串,用逗号分隔:

declare v_sql varchar(1000); --Bigger than maximum possible result query...
declare stmt  varchar(1000);
declare return_result integer;
set v_sql = 'select case when count(*) > 0 then 1 else 0 end' &
     ' from acls WHERE acls.id = curid and user in (' &  users & ')' &
     ' group by (1)';
prepare stmt from v_sql;
open mycur;
fetch mycur into return_result;
close mycur;
return return_result;

这假设用户是数值。如果它们是字符串,它将不起作用,因为必须在in子句中引用每个用户。

于 2013-03-14T14:41:14.933 回答