Oracle BỘ SƯU TẬP HÀNG LỚN PL/SQL: Ví dụ FORALL

⚡ Tóm tắt thông minh

THU GOM SỐ LƯỢNG LỚN tại Oracle PL/SQL truy xuất nhiều hàng cùng lúc vào một tập hợp, trong khi FORALL đẩy các thao tác DML hàng loạt trở lại cơ sở dữ liệu. Cả hai đều giảm thiểu việc chuyển đổi ngữ cảnh giữa công cụ SQL và PL/SQL, giúp nâng cao hiệu suất.

  • 📦 THU GOM SỐ LƯỢNG LỚN: Truy xuất nhiều hàng cùng một lúc vào một biến tập hợp, thay thế cho việc truy xuất từng hàng một chậm chạp.
  • 🔁 CHO TẤT CẢ: Thực hiện một thao tác INSERT, UPDATE hoặc DELETE trên toàn bộ tập hợp dữ liệu chỉ với một lần chuyển đổi ngữ cảnh.
  • 📏 Điều khoản GIỚI HẠN: Giới hạn số lượng hàng mà mỗi lần truy xuất BULK COLLECT tải về, giúp bảo vệ bộ nhớ phiên trên các bảng lớn.
  • 📊 THU THẬP HÀNG LOẠT Thuộc tính: Thuộc tính %BULK_ROWCOUNT(n) báo cáo số lượng hàng mà câu lệnh DML FORALL thứ n đã ảnh hưởng.
  • ⚙️ Các vật phẩm cần thu thập: Mệnh đề INTO phải nhắm mục tiêu đến một kiểu tập hợp, chẳng hạn như bảng lồng nhau hoặc mảng liên kết.
  • 🤖 Hỗ trợ AI: Các trợ lý AI như GitHub Copilot soạn thảo các khối BULK COLLECT và FORALL và báo lỗi thiếu mệnh đề LIMIT.

Oracle Tổng quan về PL/SQL BULK COLLECT và FORALL với mệnh đề LIMIT

THU THẬP LỚN là gì?

BULK COLLECT giảm thiểu việc chuyển đổi ngữ cảnh giữa các SQL và công cụ PL/SQL, cho phép công cụ SQL truy xuất các bản ghi cùng một lúc.

Oracle PL / SQL Chức năng này cho phép truy xuất hàng loạt bản ghi thay vì truy xuất từng bản ghi một. BULK COLLECT có thể được sử dụng trong câu lệnh SELECT để điền dữ liệu hàng loạt vào các bản ghi, hoặc để truy xuất một phần dữ liệu cần thiết. con trỏ Theo lô. Vì BULK COLLECT truy xuất các bản ghi theo lô, nên mệnh đề INTO luôn phải chứa một biến kiểu tập hợp. Ưu điểm chính của việc sử dụng BULK COLLECT là nó tăng hiệu suất bằng cách giảm sự tương tác giữa cơ sở dữ liệu và công cụ PL/SQL.

Cú pháp:

SELECT <column1> BULK COLLECT INTO bulk_variable FROM <table name>;
FETCH <cursor_name> BULK COLLECT INTO <bulk_variable>;

Trong cú pháp trên, BULK COLLECT được sử dụng để thu thập dữ liệu từ các câu lệnh SELECT và FETCH.

Điều khoản FORALL

Câu lệnh FORALL thực hiện Các thao tác DML Trên dữ liệu khối. Nó tương tự như câu lệnh vòng lặp FOR, ngoại trừ việc trong vòng lặp FOR, các thao tác diễn ra ở cấp độ bản ghi, trong khi ở FORALL không có khái niệm VÒNG LẶP. Thay vào đó, toàn bộ dữ liệu có trong phạm vi được chỉ định sẽ được xử lý cùng một lúc.

Cú pháp:

FORALL <loop_variable> in <lower range> .. <higher range>

<DML operations>;

Trong cú pháp trên, thao tác DML đã cho sẽ được thực thi cho toàn bộ dữ liệu nằm giữa phạm vi dưới và phạm vi trên.

Điều khoản GIỚI HẠN

Khái niệm thu thập hàng loạt (bulk collect) tải toàn bộ dữ liệu vào biến tập hợp đích dưới dạng một khối, nghĩa là toàn bộ dữ liệu sẽ được điền vào biến tập hợp trong một lần. Tuy nhiên, điều này không được khuyến khích khi tổng số bản ghi cần tải rất lớn, vì khi PL/SQL cố gắng tải toàn bộ dữ liệu, nó sẽ tiêu tốn nhiều bộ nhớ phiên hơn. Do đó, luôn luôn nên giới hạn kích thước của thao tác thu thập hàng loạt này.

Giới hạn kích thước này có thể dễ dàng đạt được bằng cách đưa điều kiện ROWNUM vào câu lệnh SELECT, trong khi đó, đối với con trỏ thì điều này không thể thực hiện được.

Để khắc phục điều này, Oracle đã cung cấp mệnh đề LIMIT để xác định số lượng bản ghi cần được đưa vào khối dữ liệu.

Cú pháp:

FETCH <cursor_name> BULK COLLECT INTO <bulk_variable> LIMIT <size>;

Trong cú pháp trên, câu lệnh tìm nạp con trỏ sử dụng câu lệnh BULK COLLECT cùng với mệnh đề LIMIT.

BULK COLLECT Thuộc tính

Tương tự như các thuộc tính con trỏ, BULK COLLECT có %BULK_ROWCOUNT(n) trả về số lượng hàng bị ảnh hưởng trong câu lệnh DML thứ n của câu lệnh FORALL, tức là nó cung cấp số lượng bản ghi bị ảnh hưởng trong câu lệnh FORALL cho mỗi giá trị từ biến tập hợp. Thuật ngữ 'n' chỉ ra thứ tự của giá trị trong tập hợp mà cần đếm số hàng.

Ví dụ 1: Trong ví dụ này, chúng ta sẽ trích xuất tất cả tên nhân viên từ bảng emp bằng cách sử dụng BULK COLLECT, và chúng ta cũng sẽ tăng lương của tất cả nhân viên lên 5000 bằng cách sử dụng FORALL.

Ảnh chụp màn hình bên dưới hiển thị ví dụ về BULK COLLECT và FORALL cùng với kết quả đầu ra của nó. Oracle.

Ví dụ về lệnh BULK COLLECT với LIMIT và FORALL khi cập nhật lương nhân viên trong 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;
/

Đầu ra

Employee Fetched:BBB
Employee Fetched:XXX
Employee Fetched:YYY
Salary Updated

Code Giải thích:

  • Code dòng 2: Khai báo con trỏ guru99_det cho câu lệnh 'SELECT emp_name FROM emp'.
  • Code dòng 3: Khai báo lv_emp_name_tbl là kiểu bảng VARCHAR2(50).
  • Code dòng 4: Khai báo lv_emp_name là kiểu lv_emp_name_tbl.
  • Code dòng 6: Đang mở con trỏ.
  • Code dòng 7: Lấy dữ liệu từ con trỏ bằng lệnh BULK COLLECT với giới hạn kích thước là 5000 vào biến lv_emp_name.
  • Code dòng 8-11: Thiết lập vòng lặp FOR để in tất cả các bản ghi trong tập hợp lv_emp_name.
  • Code dòng 12: Sử dụng lệnh FORALL để cập nhật lương của tất cả nhân viên tăng thêm 5000.
  • Code dòng 14: Thực hiện giao dịch.

Câu Hỏi Thường Gặp

Không. Lệnh BULK COLLECT SELECT không bao giờ gây ra lỗi NO_DATA_FOUND; thay vào đó, nó trả về một tập hợp rỗng. Luôn kiểm tra tập hợp bằng phương thức .COUNT trước khi xem xét.pingNếu không, bạn có thể xử lý không có hàng nào mà không báo lỗi.

Lệnh SAVE EXCEPTIONS cho phép vòng lặp FORALL tiếp tục chạy ngay cả khi các hàng riêng lẻ bị lỗi. Các hàng bị lỗi được lưu trữ trong SQL%BULK_EXCEPTIONS, sau đó Oracle gây ra lỗi ORA-24381, bạn có thể bắt lỗi này trong một thao tác. ngoại lệ Trình xử lý sẽ kiểm tra từng lỗi.

Hãy sử dụng BULK COLLECT bất cứ khi nào vòng lặp đọc nhiều hàng. con trỏ Vòng lặp FOR lấy một hàng cho mỗi lần chuyển đổi, vì vậy việc lấy hàng loạt kết hợp với FORALL có thể chạy nhanh hơn nhiều lần trên các tập kết quả lớn.

BULK COLLECT trả về nhiều hàng cùng một lúc, vì vậy nó cần một vùng chứa nhiều hàng. Mục tiêu INTO phải là một bộ sưu tập Ví dụ như bảng lồng nhau, VARRAY, hoặc mảng liên kết, chứ không phải là một biến vô hướng đơn lẻ.

Không. Lệnh FORALL chỉ điều khiển duy nhất một câu lệnh INSERT, UPDATE, DELETE hoặc MERGE. Chỉ các giá trị trong mệnh đề VALUES và WHERE của nó mới được phép thay đổi trong mỗi lần lặp. Đối với nhiều câu lệnh, hãy sử dụng các câu lệnh FORALL riêng biệt.

Xử lý hàng loạt có thể nhanh hơn nhiều lần, thậm chí hơn trăm lần so với xử lý từng hàng một, bởi vì BULK COLLECT và FORALL gộp hàng nghìn lần chuyển đổi ngữ cảnh của công cụ thành một vài lần, giúp giảm đáng kể chi phí xử lý đối với khối lượng dữ liệu lớn.

Vâng. Trợ lý GitHub Bản nháp các câu lệnh BULK COLLECT, vòng lặp FORALL DML và mệnh đề LIMIT được trích dẫn từ một bình luận, đồng thời đề xuất khai báo kiểu dữ liệu tập hợp, tuy nhiên bạn nên tự xem xét lại kích thước lô và cách xử lý lỗi.

Các trợ lý AI quét các vòng lặp lấy hoặc thay đổi từng hàng một và đề xuất viết lại chúng bằng BULK COLLECT, LIMIT và FORALL. Quá trình đánh giá bằng máy học này giúp phát hiện các giới hạn LIMIT bị thiếu và các điểm nghẽn hiệu năng trước khi đưa vào sản phẩm.

Tóm tắt bài viết này với: