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ść.

  • 📦 ODBIÓR HURTOWY: Pobiera wiele wierszy w jednym przejściu do zmiennej kolekcji, zastępując powolne pobieranie wiersz po wierszu.
  • 🔁 DLA WSZYSTKICH: Wykonuje jedną operację INSERT, UPDATE lub DELETE w całej kolekcji za pomocą jednej zmiany kontekstu.
  • 📏 Klauzula LIMIT: Ustawia limit liczby wierszy ładowanych podczas każdego pobrania BULK COLLECT, chroniąc pamięć sesji w przypadku dużych tabel.
  • 📊 Atrybuty ZBIORU MASOWEGO: Atrybut %BULK_ROWCOUNT(n) informuje, na ile wierszy wpłynęło n-te polecenie DML FORALL.
  • ⚙️ Wymagane kolekcje: Klauzula INTO musi odnosić się do typu kolekcji, takiego jak tabela zagnieżdżona lub tablica asocjacyjna.
  • 🤖 Pomoc AI: Asystenci AI, tacy jak GitHub Copilot, tworzą bloki BULK COLLECT i FORALL i sygnalizują brakującą klauzulę LIMIT.

Oracle Omówienie poleceń PL/SQL BULK COLLECT i FORALL z klauzulą ​​LIMIT

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.

Przykład BULK COLLECT z LIMIT i FORALL aktualizujący wynagrodzenie pracownika w Oracle PL / SQL

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.

FAQ

Nie. BULK COLLECT SELECT nigdy nie zgłasza NO_DATA_FOUND; zamiast tego zwraca pustą kolekcję. Zawsze testuj kolekcję metodą .COUNT przed loo.ping, w przeciwnym wypadku możesz przetworzyć zero wierszy bezgłośnie.

Funkcja SAVE EXCEPTIONS pozwala na kontynuowanie działania funkcji FORALL w przypadku błędów w poszczególnych wierszach. Błędne wiersze są zapisywane w zmiennej SQL%BULK_EXCEPTIONS, a następnie Oracle podnosi ORA-24381, który uwięzisz w wyjątek program obsługi błędów w celu sprawdzenia każdego błędu.

Użyj BULK COLLECT, gdy pętla odczytuje wiele wierszy. kursor Pętla FOR pobiera jeden wiersz na jedno przełączenie, więc pobieranie zbiorcze plus FORALL może działać znacznie szybciej w przypadku dużych zestawów wyników.

Funkcja BULK COLLECT zwraca wiele wierszy jednocześnie, dlatego wymaga kontenera wielowierszowego. Cel INTO musi być kolekcja takie jak tabela zagnieżdżona, VARRAY lub tablica asocjacyjna, a nie pojedyncza zmienna skalarna.

Nie. Nagłówek FORALL steruje dokładnie jedną operacją INSERT, UPDATE, DELETE lub MERGE. Tylko wartości w jego klauzulach VALUES i WHERE mogą się zmieniać w każdej iteracji. W przypadku kilku instrukcji należy użyć osobnych instrukcji FORALL.

Przetwarzanie zbiorcze może być od kilku do ponad stu razy szybsze niż przetwarzanie kodu wiersz po wierszu, ponieważ BULK COLLECT i FORALL łączą tysiące przełączeń kontekstowych silnika w kilka, co znacznie obniża obciążenie przy dużych wolumenach danych.

Tak. Drugi pilot GitHub tworzy szkice operacji pobierania BULK COLLECT, pętli DML FORALL i klauzul LIMIT na podstawie komentarza oraz sugeruje deklaracje typów kolekcji, choć powinieneś sam sprawdzić rozmiary partii i obsługę błędów.

Asystenci AI skanują pętle pobierające lub zmieniające wiersz po wierszu i zalecają ich przepisanie za pomocą BULK COLLECT, LIMIT i FORALL. Ta analiza uczenia maszynowego pozwala wykryć brakujące limity LIMIT i wąskie gardła wydajności przed rozpoczęciem produkcji.

Podsumuj ten post następująco: