wprowadzenie wartości z kursora do tablicy pl/sql

0

Chcę wsadzić wiersz po wierszu z kursora do tablicy zagnieżdżonej i wszystko działa bez problemu.. tylko z jakiegoś powodu, nie wiem z jakiego tworzy mi się większa tablica niż ilość wierszy z kursora i pojęcia nie mam dlaczego.. jakieś zjawisko zachodzi o którym nie wiem.. skąd 6 indeksów w tablicy skoro pętla wykonuje się 3 razy.. proszę o pomoc

DECLARE
type t_nested is table of kopia.first_name%TYPE;
tab t_nested:=t_nested();
CURSOR kursor IS
SELECT first_name FROM kopia WHERE manager_id =1 ORDER BY MANAGER_ID;
idE kopia.first_name%TYPE;
counter number:=1;
BEGIN
OPEN kursor;
LOOP
FETCH kursor INTO idE;
EXIT WHEN kursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('pętla nr:'||counter);
DBMS_OUTPUT.PUT_LINE('idemp: '||idE);
tab.extend(counter);
tab(counter):=idE;
counter:=counter+1;
END LOOP;
CLOSE kursor;
DBMS_OUTPUT.NEW_LINE;
for i in 1..tab.last loop
DBMS_OUTPUT.PUT_LINE('zmienna w tablicy:'||tab(i));
end loop;
DBMS_OUTPUT.PUT_LINE('ilość indeksów w tablicy:'||tab.count);
END;

wynik:
pętla nr:1
idemp: Stefan
pętla nr:2
idemp: Zuzanna
pętla nr:3
idemp: Edward

zmienna w tablicy:Stefan
zmienna w tablicy:Zuzanna
zmienna w tablicy:Edward
zmienna w tablicy:
zmienna w tablicy:
zmienna w tablicy:
ilość indeksów w tablicy:6

1

Robisz:

tab.extend(counter); 

a potem

counter:=counter+1;

Czyli w pierwszym przejściu pętli rozszerzasz tabelę o 1 element, potem o 2, na końcu o 3.

Zrób tab.extend(1);

A jak już zacznie działać, to zainteresuj się klauzulą FETCH ... BULK COLLECT INTO ...
Zaoszczędzisz czasu i odczytów z cache/dysku. Tylko, że przy większych ilościach (> kilkaset rekordów) też robi się to w pętli dodając opcję LIMIT n, gdzie n to liczba pobieranych w jednym przejściu rekordów.

0

Bardzo dziękuję za podpowiedź.. błąd szkolny.. ;) szukałem tam gdzie nie powinienem.. jeśli chodzi o operacje masowe to tą metodą zrobiłem najpierw to zadanie, fakt.. przy dużej ilości danych to ma znaczenie jeśli chodzi o czas.. chciałem po prostu zrobić to, że się tak wyrażę, na piechotę w ramach ćwiczeń i gimnastyki.. :)
A jeśli chodzi o metodę LIMIT bo tej używałem również.. robi się ją w pętli.. po ile wierszy powinno być tak optymalnie w paczce...? czy zależy to bardziej od posiadanych zasobów..

0

Co do LIMITu to trzeba go ustawić eksperymentalnie. Poza tym jego rozmiar też zależy od samego zapytania, np. ile danych jest w jednym rekordzie, czy będzie to full scan czy inny sposób dostępu. Możesz zacząć od 100, jak pomnożysz to przez średnią długość rekordu (avg_row_len w DBA/ALL_TABLES), to masz informację ile danych będzie pobieranych na raz. Jeśli dane będą odczytywane z dysku (a skoro potrzebujemy BULK to pewnie będą), to można tu się odnieść do rozmiaru paczki danych, którą jest w stanie dostarczyć system plików (256, 512, 1024 KB - zależy od systemu i konfiguracji, rodzaju RAID itp.). Jednak też trzeba wziąć pod uwagę, że w rzeczywistej sytuacji twoja sesja nie będzie jedyna i zwiększanie rozmiaru porcji danych wcale nie wpłynie pozytywnie na ogólną wydajność.

1 użytkowników online, w tym zalogowanych: 0, gości: 1