2017-01-11 15 views
0

私はMOD条件付きの単純な "長いループ"を使って連想配列の奇妙な値を画面に表示しようとしています。出来ますか? PLS_INTEGERは10進数ではない値(Javaのintデータ型のような)を受け入れないことを知っています。だから...私はNUMBERカウンターで試しましたが、私は同じ結果を受け取ります。どうすれば解決できますか? 。おかげWHILE LOOP内のMOD関数をPLS_INTEGERデータ型で使用するにはどうすればよいですか?

私は、画面上で取得したい
SET SERVEROUTPUT ON 

DECLARE 
    TYPE type_test IS TABLE OF VARCHAR2(45) 
     INDEX BY PLS_INTEGER; 
    t_test_5 type_test; 

    v_counter_1 PLS_INTEGER; 
    v_counter_2 NUMBER; 
BEGIN      
    t_test_5(1) := 'Test1'; 
    t_test_5(2) := 'Test2'; 
    t_test_5(3) := 'Test3'; 
    t_test_5(4) := 'Test4'; 
    t_test_5(5) := 'Test5'; 
    t_test_5(6) := 'Test6'; 
    t_test_5(7) := 'Test7'; 
    t_test_5(8) := 'Test8'; 
    t_test_5(9) := 'Test9'; 
    t_test_5(10) := 'Test10'; 

    DBMS_OUTPUT.PUT_LINE('PLS_INTEGER COUNTER TEST'); 
    v_counter_1 := t_test_5.FIRST; 
    WHILE MOD(v_counter_1, 2) <> 0 
    LOOP 
     DBMS_OUTPUT.PUT_LINE(t_test_5(v_counter_1)); 

     v_counter_1 := t_test_5.NEXT(v_counter_1); 
    END LOOP; 

    DBMS_OUTPUT.PUT_LINE(' '); 
    DBMS_OUTPUT.PUT_LINE('NUMBER COUNTER TEST'); 
    v_counter_2 := t_test_5.FIRST; 
    WHILE MOD(v_counter_2, 2) <> 0 
    LOOP 
     DBMS_OUTPUT.PUT_LINE(t_test_5(v_counter_2)); 

     v_counter_2 := t_test_5.NEXT(v_counter_2); 
    END LOOP; 
END; 

値1、3、5、7、9が、両方の状況で私が唯一の値1を取得:

Procedimiento PL/SQL terminado correctamente. 
PLS_INTEGER COUNTER TEST 
Test1 

NUMBER COUNTER TEST 
Test1 
+1

"この割り当てに' 'MOD()'を使う方法とは別に、奇数インデックス値だけを出力したい場合は、カウンタ 'j'をループして' array_name(2 * j + 1) 'を出力してください。 'mod(k、1000)= 1'のとき' 'array_name(k)'だけを出力したいのであれば、これはもっと重要です。 ''(1000 * j + 1) 'を実行すると、* much *速く実行されます。 – mathguy

+1

@mathguyこれは通常の配列では機能しますが、連想配列は疎であり、偶数インデックスごとに要素を持つことは保証されません。 – MT0

+0

@mathguyまさに! – Rattlesnake

答えて

2

問題はのタイプではありませんあなたの変数は、ループが最初の行で終わり、MOD(v_counter_1, 2) <> 0と一致しないため、すべての行をスキャンしないという事実にあります。

DECLARE 
    TYPE type_test IS TABLE OF VARCHAR2(45) 
     INDEX BY PLS_INTEGER; 
    t_test_5 type_test; 

    v_counter_1 PLS_INTEGER; 
    v_counter_2 NUMBER; 
BEGIN      
    t_test_5(1) := 'Test1'; 
    t_test_5(2) := 'Test2'; 
    t_test_5(3) := 'Test3'; 
    t_test_5(4) := 'Test4'; 
    t_test_5(5) := 'Test5'; 
    t_test_5(6) := 'Test6'; 
    t_test_5(7) := 'Test7'; 
    t_test_5(8) := 'Test8'; 
    t_test_5(9) := 'Test9'; 
    t_test_5(10) := 'Test10'; 

    DBMS_OUTPUT.PUT_LINE('PLS_INTEGER COUNTER TEST'); 
    v_counter_1 := t_test_5.FIRST; 
    WHILE v_counter_1 is not null 
    LOOP 
     if mod(v_counter_1, 2) != 0 then 
      DBMS_OUTPUT.PUT_LINE(t_test_5(v_counter_1)); 
     end if; 
     v_counter_1 := t_test_5.NEXT(v_counter_1); 
    END LOOP; 
END; 

結果:

必要なもの

MOD(v_counter_1, 2) = 0終了ループ、単にあなたの条件に一致する行のみの値を印刷し、すべての行をスキャンループではありません

PLS_INTEGER COUNTER TEST 
Test1 
Test3 
Test5 
Test7 
Test9 
+1

私はそれを打ち負かすが、私は問題の説明を追加する: 'WHILE'ループは終了条件を打つことによって最初の実行で終了していた。 – gmiley

+1

@gmileyあなたの答えをありがとう。今、私はWHILE状態を理解しています。EXIT条件は、単純なLoop節と同様です。終了時...あなたの助けに感謝します! – Rattlesnake

1

whileループは、カウンタの値が偶数になるとすぐに終了します。したがって、2に達するとすぐにループが終了します。何が欲しいのは、すべての値をループしているが、偶数値をスキップ:

WHILE (v_counter_1 IS NOT NULL) 
LOOP 
    IF MOD(v_counter_1, 2) = 0 THEN 
    v_counter_1 := t_test_5.NEXT(v_counter_1); 
    CONTINUE; 
    END IF; 
    DBMS_OUTPUT.PUT_LINE(t_test_5(v_counter_1)); 
    v_counter_1 := t_test_5.NEXT(v_counter_1); 
END LOOP; 

あなたがまばらな配列を持っているつもりされていない場合、あなたは、連想配列を使用する必要はありません。

DECLARE 
    TYPE type_test IS TABLE OF VARCHAR2(45); 
    t type_test := type_test('Test1', 'Test2', 'Test3', 'Test4', 'Test5', 'Test6'); 
BEGIN 
    FOR i = 1 .. t.COUNT/2 LOOP 
    DBMS_OUTPUT.PUT_LINE(t(2*i-1)); 
    END LOOP; 
END; 
/
関連する問題