2016-09-15 6 views
2

ただ、理論的質問:トリムされたPLSQLコレクションの最後の要素を削除してPLSQLコレクションに伝えることはできますか?

ネストした表が原因lastまでnextの間でfirstからインデックスの順序で穴を創設することによって証明することができ、欠失、スパースになることができます。 しかし、lastのインデックスが削除された場合、コレクションの境界は、lastインデックスがトリミングされた場合(またはコレクションが決してそのインデックスに拡張されなかった場合)とまったく同じです。 この違いを区別する方法はありますか?言い換えれば

declare 
    type ct is table of varchar2(200); 
    a ct := ct('x','y','z'); 
    b ct := ct('x','y','z'); 
begin 
    a.delete(3); 
    b.trim(); 
    -- first=1, last=2, count=2 here for both a and b 
    a(3) := 'l'; -- legal since delete keeps room for 3rd element extended 
    --b(3) := 'l'; -- illegal since trim is inversion of extend 
end; 

、アリスが削除され、ボブは、トリム、私は(インデックス last+1に挿入し、潜在的なORA-06533 Subscript beyond countエラーをキャッチしようとする試みを行うことを除いて)誰がどのコレクションを作っ伝えることができますか?ありがとう!

答えて

1

ここでの違いはdelete後、ネストされた表がスパースなるがtrimた後、それはままであることです。 PL/SQLでは、ネストした表が疎かまたは密集しているかどうかを確認するためのツールはありません。プログラマは、疎または密なネストした表を使用している場合は、すべての時間を知っておく必要があります。 a.delete(3)またはb.trim PL/SQLの後にあなたの特定の例では

はあなたにa(3) := 'x'b(3) := 'x'が有効であるかどうかをプログラム的にチェックするための特別な工具を提供していません。あなたが指摘したことを除いて、それを試して、潜在的な例外をキャッチします。一般的には、ネストした表のサイズを把握する必要があります。

私の経験則では、常にネストされたテーブルを密に保ち、疎なコレクションの場合は連想配列を使用しています。ネストした表要素のサブセットのみが必要な場合は、そのサブセットの新しい密集した表を作成します。

declare 
    type str_list_t is table of varchar2(1); 

    a str_list_t := str_list_t('a', 'b', 'c'); -- dense 
    b str_list_t := str_list_t('a', 'b', 'c'); -- dense 

    procedure d(p_strs in str_list_t) is 
    s varchar2(32767); 
    begin 
    s := '(count ' || p_strs.count || ')'; 
    s := s || '(first ' || p_strs.first || ')'; 
    s := s || '(last ' || p_strs.last || ')'; 

    s := s || '('; 
    for i in p_strs.first .. p_strs.last 
    loop 
     s := s || '(' || i || ' ' || p_strs(i) || ')'; 
    end loop; 
    s := s || ')'; 

    dbms_output.put_line(s); 
    end; 
begin 
    a.delete(3); d(a); -- collection becomes sparse 
    b.trim;  d(b); -- remains dense 

    -- exists won't help you as a(3) doesn't exists and exists returns false 
    if a.exists(3) then a(3) := 'C'; end if; 
    if b.exists(3) then b(3) := 'C'; end if; 

    d(a); 
    d(b); 

    a(3) := 'D'; d(a); -- ok 
    b(3) := 'D'; d(b); -- ORA-06533: Subscript beyond count 
end; 
/

結果

(count 2)(first 1)(last 2)((1 a)(2 b)) 
(count 2)(first 1)(last 2)((1 a)(2 b)) 
(count 2)(first 1)(last 2)((1 a)(2 b)) 
(count 2)(first 1)(last 2)((1 a)(2 b)) 
(count 3)(first 1)(last 3)((1 a)(2 b)(3 D)) 
declare 
* 
ERROR at line 1: 
ORA-06533: Subscript beyond count 
ORA-06512: at line 35 
+0

徹底的に答えてくれてありがとう。私はそれを期待していた。このような情報は容易に入手できません(例えば、 'limit'はネストしたテーブルには利用されません。内部容量を返すことができます)。 –

関連する問題