Oracle ZBIERANIE ZBIORCZE PL/SQL: FORALL Przykład
⚡ Inteligentne podsumowanie
ODBIÓR HURTOWY w Oracle PL/SQL pobiera wiele wierszy jednocześnie do kolekcji, podczas gdy FORALL przesyła masowe dane DML z powrotem do bazy danych. Oba języki eliminują przełączanie kontekstu między silnikami SQL i PL/SQL, zwiększając wydajność.
Co to jest ZBIERANIE BULKOWE?
BULK COLLECT redukuje przełączanie kontekstu między SQL i silnika PL/SQL, umożliwiając silnikowi SQL jednoczesne pobieranie rekordów.
Oracle PL / SQL Zapewnia funkcjonalność pobierania rekordów zbiorczo, zamiast pobierania ich pojedynczo. Ta funkcja BULK COLLECT może być używana w poleceniu SELECT do zbiorczego pobierania rekordów lub do pobierania kursor Masowo. Ponieważ BULK COLLECT pobiera rekordy zbiorczo, klauzula INTO powinna zawsze zawierać zmienną typu kolekcji. Główną zaletą korzystania z BULK COLLECT jest zwiększenie wydajności poprzez ograniczenie interakcji między bazą danych a silnikiem PL/SQL.
Składnia:
SELECT <column1> BULK COLLECT INTO bulk_variable FROM <table name>; FETCH <cursor_name> BULK COLLECT INTO <bulk_variable>;
W powyższej składni polecenie BULK COLLECT służy do zbierania danych z poleceń SELECT i FETCH.
Klauzula FORALL
Instrukcja FORALL wykonuje Operacje DML na danych zbiorczych. Przypomina instrukcję pętli FOR, z tą różnicą, że w pętli FOR działania są wykonywane na poziomie rekordu, podczas gdy w pętli FORALL nie ma koncepcji pętli LOOP. Zamiast tego wszystkie dane obecne w danym zakresie są przetwarzane jednocześnie.
Składnia:
FORALL <loop_variable> in <lower range> .. <higher range>
<DML operations>;
W powyższej składni podana operacja DML zostanie wykonana dla wszystkich danych znajdujących się pomiędzy dolnym i górnym zakresem.
Klauzula LIMIT
Koncepcja zbiorczego gromadzenia danych polega na załadowaniu wszystkich danych do zmiennej kolekcji docelowej w trybie zbiorczym, tj. wszystkie dane zostaną wprowadzone do zmiennej kolekcji za jednym razem. Nie jest to jednak zalecane, gdy całkowita liczba rekordów do załadowania jest bardzo duża, ponieważ próba załadowania całych danych przez PL/SQL zużywa więcej pamięci sesji. Dlatego zawsze warto ograniczyć rozmiar tej operacji zbiorczego gromadzenia danych.
To ograniczenie rozmiaru można łatwo osiągnąć, wprowadzając warunek ROWNUM w poleceniu SELECT, natomiast w przypadku kursora nie jest to możliwe.
Aby to przezwyciężyć, Oracle zapewnił klauzulę LIMIT, która definiuje liczbę rekordów, które muszą zostać uwzględnione w przesyłce zbiorczej.
Składnia:
FETCH <cursor_name> BULK COLLECT INTO <bulk_variable> LIMIT <size>;
W powyższej składni polecenie pobierania kursora używa polecenia BULK COLLECT wraz z klauzulą LIMIT.
ZBIERAJ ZBIORCZO Atrybuty
Podobnie jak atrybuty kursora, BULK COLLECT ma funkcję %BULK_ROWCOUNT(n), która zwraca liczbę wierszy objętych n-tą instrukcją DML instrukcji FORALL, tj. podaje liczbę rekordów objętych instrukcją FORALL dla każdej pojedynczej wartości ze zmiennej kolekcji. Parametr „n” wskazuje sekwencję wartości w kolekcji, dla której potrzebna jest liczba wierszy.
1 przykład: W tym przykładzie za pomocą polecenia BULK COLLECT wyświetlimy nazwiska wszystkich pracowników z tabeli emp, a także zwiększymy pensję wszystkich pracowników o 5000 za pomocą polecenia FORALL.
Poniższy zrzut ekranu przedstawia przykład BULK COLLECT i FORALL wraz z jego wynikami w Oracle.
DECLARE CURSOR guru99_det IS SELECT emp_name FROM emp; TYPE lv_emp_name_tbl IS TABLE OF VARCHAR2(50); lv_emp_name lv_emp_name_tbl; BEGIN OPEN guru99_det; FETCH guru99_det BULK COLLECT INTO lv_emp_name LIMIT 5000; FOR c_emp_name IN lv_emp_name.FIRST .. lv_emp_name.LAST LOOP Dbms_output.put_line('Employee Fetched:'||c_emp_name); END LOOP; FORALL i IN lv_emp_name.FIRST .. lv_emp_name.LAST UPDATE emp SET salary=salary+5000 WHERE emp_name=lv_emp_name(i); COMMIT; Dbms_output.put_line('Salary Updated'); CLOSE guru99_det; END; /
Wydajność
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY Salary Updated
Code Wyjaśnienie:
- Code linia 2: Deklaracja kursora guru99_det dla polecenia „SELECT emp_name FROM emp”.
- Code linia 3: Deklarowanie lv_emp_name_tbl jako typu tabeli VARCHAR2(50).
- Code linia 4: Deklarowanie lv_emp_name jako typu lv_emp_name_tbl.
- Code linia 6: Otwarcie kursora.
- Code linia 7: Pobieranie kursora za pomocą BULK COLLECT z rozmiarem LIMIT równym 5000 do zmiennej lv_emp_name.
- Code wiersz 8-11: Konfigurowanie pętli FOR w celu wydrukowania wszystkich rekordów w kolekcji lv_emp_name.
- Code linia 12: Użycie FORALL do zaktualizowania pensji wszystkich pracowników o kwotę 5000.
- Code linia 14: Zobowiązanie się transakcja.


