2009-11-13 5 views
7

이것은 "더 좋은 방법이 있어야합니다"라는 질문 중 하나입니다. 문제를 설정 한 다음 해킹 된 솔루션을 제공하고 더 나은 솔루션을 제안 할 수 있습니다. 감사!PL/SQL에서 연관 배열 재설정 중?

는 의미를

DECLARE 
TYPE foo_record IS RECORD (foo%type, bar%type); 
TYPE foo_records IS TABLE OF foo_record INDEX BY PLS_INTEGER; 
arr_foos foo_records; 

CURSOR monkeys is SELECT primates FROM zoo; 
row_monkey monkeys%rowtype; 
BEGIN 
FOR row_monkey IN monkeys loop 
    /* 
    at this point in each iteration I need to have the associative array 
    arr_foos in its original state. if this were java, I'd declare it 
    right here and its scope would be limited to this iteration. However, 
    this is not java, so the scope of the array is effectively global and 
    I can't have one iteration's data meddle with the next. 
    */ 
    null; 
END LOOP; 
END; 

합니까 SQL/PL의이 작은 맛있는 가벼운 음식을 수 있습니다? 기본적으로 뭔가를 재설정해야합니다. 0에서 시작하는 숫자 인 경우 number : = 0; 모든 반복의 맨 위에 놓고 끝내십시오. 그러나 이것은 숫자가 아니며, 단지 0으로 초기화 할 수있는 유형입니다 : = 0.

어쨌든, 내 해킹에 :

DECLARE 
TYPE foo_record IS RECORD (foo%type, bar%type); 
TYPE foo_records IS TABLE OF foo_record INDEX BY PLS_INTEGER; 
arr_foos foo_records; 
arr_foos_reset foo_records; 

CURSOR monkeys is SELECT primates FROM zoo; 
row_monkey monkeys%rowtype; 
BEGIN 
FOR row_monkey IN monkeys loop 
    arr_foos := arr_foos_reset; 
    null; 
END LOOP; 
END; 

은 내가 원래 상태로 동일한 유형의 회원을 유지 관리 할 수 ​​있다면, 난 그냥 다시 어떤 값으로 작업 변수를 설정할 수 있다는 생각 원래의 것입니다. 놀랍게도 충분히 작동합니다 (생각합니다.)하지만 더 나은 방법이 있어야합니다. 누구든지 도와 줄 수 있습니까?

T'anks!

+1

마이너 nitpick을 : 당신은'row_monkey 원숭이에게 %의 ROWTYPE을 선언 할 필요가 없습니다 '. 이와 같은 커서 FOR 루프는 선언을 수행하며 루프 본문으로 제한됩니다. 이 코드에서 변수는 두 번 선언되고 내부 버전은 바깥 쪽 버전을 음영 처리합니다. 그것은 문제가 아니에요 - 그냥 다른 사람이 읽고 이것을 추가 할 줄 알았는데. – AdamRossWalker

답변

18

가장 쉬운 방법 :

arr_foos.Delete(); 

다른 방법은 FOR 루프 내부의 변수를 선언하는 것입니다. 이 방법은 매 패스마다 재생성됩니다.

DECLARE 
TYPE foo_record IS RECORD (foo%type, bar%type); 
TYPE foo_records IS TABLE OF foo_record INDEX BY PLS_INTEGER;  

CURSOR monkeys is SELECT primates FROM zoo; 
row_monkey monkeys%rowtype; 
BEGIN 
FOR row_monkey IN monkeys loop 
    DECLARE 
    arr_foos foo_records; 
    BEGIN 
    null; 
    END; 
END LOOP; 
END; 
+2

감사합니다. BEGIN 후에 DECLARE라고 말할 수 있다는 것을 깨닫지 못했습니다. (: – steve

+2

당신은 C#이나 Java에서 try/catch와 같은 작은 코드 블록에서 예외를 잡을 수 있습니다.) 내 의견으로는 매우 유용한 기능입니다. – Majkel

1

당신이 수집에 동물원 테이블에서 데이터를 읽을 건가요 : 이것처럼

? 자동

DECLARE 
    type foos_ts is table of zoo.foo%type index by pls_integer; 
    foos foos_t; 
BEGIN 
    select foo 
    bulk collect into foos 
    from zoo; 
    ... 
END; 

대량 수집 인출하기 전에 컬렉션을 지우고 더 빨리 루프에서 행 단위를 판독 한 후 작동 : 그리고 거기에 더 나은 방법입니다. 불행히도 레코드로 작동하지 않으므로 각 필드마다 여러 PL/SQL 테이블이 필요합니다.

여기에서 추가 정보를 찾을 수 있습니다 : Retrieving Query Results into Collections with the BULK COLLECT Clause

+0

좋은 팁, 고마워요. – steve