1つのクエリでpl/sql連想配列にデータを選択しようとしています。ハードコードされたキーでこれを実行できることはわかっていますが、代わりに別の列(キー列)を参照できる方法があるかどうかを確認したいと思いました。
DECLARE
TYPE VarAssoc IS TABLE OF varchar2(2) INDEX BY varchar2(3);
vars VarAssoc;
BEGIN
SELECT foo, bar INTO vars(foo) FROM schema.table;
END;
これを行うとfooを宣言する必要があるというエラーが表示されます。関連付けられた配列を1つのクエリで作成する方法はありますか、それともFORループにフォールバックする必要がありますか?
APCの回答についてのコメントを読んでください。自分でこれを理解したようです。しかし、私は将来の検索者のためにとにかく答えを入れると思った。
これはより単純なコードですが、BULK COLLECTを使用する速度の利点はありません。クエリによって返された行をループして、連想配列の要素を個別に設定するだけです。
DECLARE
TYPE VarAssoc IS TABLE OF varchar2(200) INDEX BY varchar2(30);
vars VarAssoc;
BEGIN
FOR r IN (SELECT table_name,tablespace_name FROM user_tables) LOOP
vars(r.table_name) := r.tablespace_name;
END LOOP;
dbms_output.put_line( vars('Java$OPTIONS') );
END;
それが可能であるならばそれはきちんとしているでしょう、しかしそれはこれを達成する簡単な方法ではありません。
私たちができることは、データを通常のPL/SQLコレクションにロードし、それを連想配列にロードすることです。これがテーブルをループするだけよりも速いかどうかは、問題です。データの負荷を処理しているのでなければ、おそらく問題ではありません。
このテストデータを考えると...
SQL> select * from t23
2 order by c1
3 /
C1 C2
-- ---
AA ABC
BB BED
CC CAR
DD DYE
EE EYE
ZZ Zoo
6 rows selected.
SQL>
... 2つの手順で連想配列を設定できます。
SQL> set serveroutput on
SQL>
SQL> declare
2 type varassoc is table of varchar2(3) index by varchar2(2);
3 vars varassoc;
4
5 type nt is table of t23%rowtype;
6 loc_nt nt;
7
8 begin
9 select * bulk collect into loc_nt from t23;
10 dbms_output.put_line('no of recs = '||sql%rowcount);
11
12 for i in loc_nt.first()..loc_nt.last()
13 loop
14 vars(loc_nt(i).c1) := loc_nt(i).c2;
15 end loop;
16
17 dbms_output.put_line('no of vars = '||vars.count());
18
19 dbms_output.put_line('ZZ = '||vars('ZZ'));
20
21 end;
22 /
no of recs = 6
no of vars = 6
ZZ = Zoo
PL/SQL procedure successfully completed.
SQL>
本当の問題は、おそらく連想配列へのデータ投入がテーブル内の行を選択することよりも優れているかどうかです。確かに11g Enterpriseエディションを使用している場合は、代わりに 結果セットキャッシュ を検討する必要があります。
連想配列と完全に結婚していますか?そして、文字キーを使用して配列に対してルックアップを実行できるようにしたいので、これを行っていると思います。
もしそうなら、代わりにこれをコレクション型として実装することを検討しましたか?
例えば.
CREATE OR REPLACE TYPE VAR_ASSOC as OBJECT(
KEYID VARCHAR2(3),
DATAVAL VARCHAR2(2)
)
/
CREATE OR REPLACE TYPE VAR_ASSOC_TBL AS TABLE OF VAR_ASSOC
/
CREATE OR REPLACE PROCEDURE USE_VAR_ASSOC_TBL
AS
vars Var_Assoc_tbl;
-- other variables...
BEGIN
select cast ( multiset (
select foo as keyid,
bar as dataval
from schema.table
) as var_Assoc_tbl
)
into vars
from dual;
-- and later, when you want to do your lookups
select ot.newfoo
,myvars.dataval
,ot.otherval
into ....
from schema.other_Table ot
join table(vars) as myvars
on ot.newfoo = myvars.keyid;
end;
/
これにより、文字のキー値による検索が可能になり、すべてを一括で実行できます。