测试DB2 SQL PL中的数组成员资格

时间:2013-03-14 13:25:06

标签: arrays db2 sql-pl

我正在将存储过程代码从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;

但是我在DB2中找不到等价的MEMBER OF

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的模式匹配。
  3. 有更好的方法吗?请记住,数组来自外部代码,不能作为我可以JOIN或任何相关的表格传递。

1 个答案:

答案 0 :(得分:0)

您可以使用associative array(在DB2 9.7+中提供)和array_exists predicate来执行此操作。我不确定这对于传递给程序的内容是否可行。

然而,我发现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子句中引用每个用户。