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;

私は2つの選択肢を見ます:

  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 に答える