Oracle Con trỏ PL/SQL: Vòng lặp ngầm, rõ ràng, vòng lặp For với ví dụ
CURSOR trong PL/SQL là gì?
Con trỏ là một con trỏ tới vùng ngữ cảnh này. Oracle tạo vùng ngữ cảnh để xử lý câu lệnh SQL chứa tất cả thông tin về câu lệnh.
PL/SQL cho phép lập trình viên điều khiển vùng ngữ cảnh thông qua con trỏ. Một con trỏ giữ các hàng được câu lệnh SQL trả về. Tập hợp các hàng mà con trỏ giữ được gọi là tập hợp hoạt động. Những con trỏ này cũng có thể được đặt tên để chúng có thể được tham chiếu từ một vị trí khác của mã.
Con trỏ có hai loại.
- Con trỏ ngầm
- Con trỏ rõ ràng
Con trỏ ngầm
Bất cứ khi nào bất kỳ hoạt động DML nào xảy ra trong cơ sở dữ liệu, một con trỏ ẩn sẽ được tạo để chứa các hàng bị ảnh hưởng trong hoạt động cụ thể đó. Những con trỏ này không thể được đặt tên và do đó chúng không thể được kiểm soát hoặc tham chiếu từ một vị trí khác của mã. Chúng ta chỉ có thể tham chiếu đến con trỏ gần đây nhất thông qua thuộc tính con trỏ.
Con trỏ rõ ràng
Các lập trình viên được phép tạo vùng ngữ cảnh được đặt tên để thực thi các hoạt động DML của họ nhằm có nhiều quyền kiểm soát hơn đối với nó. Con trỏ rõ ràng phải được xác định trong phần khai báo của Khối PL/SQLvà nó được tạo cho câu lệnh 'SELECT' cần được sử dụng trong mã.
Dưới đây là các bước liên quan đến việc làm việc với con trỏ rõ ràng.
- Khai báo con trỏ Khai báo con trỏ đơn giản có nghĩa là tạo một vùng ngữ cảnh được đặt tên cho câu lệnh 'SELECT' được xác định trong phần khai báo. Tên của vùng ngữ cảnh này giống với tên con trỏ.
- Con trỏ mởViệc mở con trỏ sẽ hướng dẫn PL / SQL để cấp phát bộ nhớ cho con trỏ này. Nó sẽ làm cho con trỏ sẵn sàng để tìm nạp các bản ghi.
- Lấy dữ liệu từ con trỏTrong quá trình này, câu lệnh 'SELECT' được thực thi và các hàng được tìm nạp sẽ được lưu trữ trong bộ nhớ được phân bổ. Bây giờ chúng được gọi là bộ hoạt động. Tìm nạp dữ liệu từ con trỏ là một hoạt động ở cấp độ bản ghi, nghĩa là chúng ta có thể truy cập dữ liệu theo cách từng bản ghi. Mỗi câu lệnh tìm nạp sẽ tìm nạp một tập hoạt động và chứa thông tin của bản ghi cụ thể đó. Câu lệnh này giống như câu lệnh 'SELECT' tìm nạp bản ghi và gán cho biến trong mệnh đề 'INTO', nhưng nó sẽ không đưa ra bất kỳ ngoại lệ nào.
- Đóng con trỏKhi tất cả bản ghi đã được tìm nạp ngay bây giờ, chúng ta cần đóng con trỏ để giải phóng bộ nhớ được phân bổ cho vùng ngữ cảnh này.
cú pháp
DECLARE CURSOR <cursor_name> IS <SELECT statement^> <cursor_variable declaration> BEGIN OPEN <cursor_name>; FETCH <cursor_name> INTO <cursor_variable>; . . CLOSE <cursor_name>; END;
- Trong cú pháp trên, phần khai báo chứa khai báo con trỏ và biến con trỏ trong đó dữ liệu được tìm nạp sẽ được gán.
- Con trỏ được tạo cho câu lệnh 'SELECT' được đưa ra trong phần khai báo con trỏ.
- Trong phần thực thi, con trỏ khai báo được mở, tìm nạp và đóng.
Thuộc tính con trỏ
Cả con trỏ ngầm và con trỏ rõ ràng đều có những thuộc tính nhất định có thể được truy cập. Các thuộc tính này cung cấp thêm thông tin về hoạt động của con trỏ. Dưới đây là các thuộc tính con trỏ khác nhau và cách sử dụng chúng.
Thuộc tính con trỏ | Mô tả Chi tiết |
---|---|
%THÀNH LẬP | Nó trả về kết quả Boolean 'TRUE' nếu thao tác tìm nạp gần đây nhất đã tìm nạp một bản ghi thành công, nếu không nó sẽ trả về FALSE. |
%KHÔNG TÌM THẤY | Điều này hoạt động ngược lại với %FOUND, nó sẽ trả về 'TRUE' nếu thao tác tìm nạp gần đây nhất không thể tìm nạp bất kỳ bản ghi nào. |
%ISOMỞ | Nó trả về kết quả Boolean 'TRUE' nếu con trỏ đã cho đã được mở, nếu không nó sẽ trả về 'FALSE' |
%ĐẾM SỐ HÀNG | Nó trả về giá trị số. Nó đưa ra số lượng bản ghi thực tế bị ảnh hưởng bởi hoạt động DML. |
Ví dụ về con trỏ rõ ràng:
Trong ví dụ này, chúng ta sẽ xem cách khai báo, mở, tìm nạp và đóng con trỏ rõ ràng.
Chúng tôi sẽ chiếu tất cả tên nhân viên từ bảng emp bằng con trỏ. Chúng tôi cũng sẽ sử dụng thuộc tính con trỏ để đặt vòng lặp tìm nạp tất cả bản ghi từ con trỏ.
DECLARE CURSOR guru99_det IS SELECT emp_name FROM emp; lv_emp_name emp.emp_name%type; BEGIN OPEN guru99_det; LOOP FETCH guru99_det INTO lv_emp_name; IF guru99_det%NOTFOUND THEN EXIT; END IF; Dbms_output.put_line(‘Employee Fetched:‘||lv_emp_name); END LOOP; Dbms_output.put_line(‘Total rows fetched is‘||guru99_det%R0WCOUNT); CLOSE guru99_det; END: /
Đầu ra
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY Total rows fetched is 3
Giải thích mã
- Dòng mã 2: Khai báo con trỏ guru99_det cho câu lệnh 'SELECT emp_name FROM emp'.
- Dòng mã 3: Khai báo biến lv_emp_name.
- Dòng mã 5: Mở con trỏ guru99_det.
- Dòng mã 6: Đặt câu lệnh vòng lặp Cơ bản để tìm nạp tất cả các bản ghi trong bảng 'emp'.
- Dòng mã 7: Tìm nạp dữ liệu guru99_det và gán giá trị cho lv_emp_name.
- Dòng mã 9: Sử dụng thuộc tính con trỏ '%NOTFOUND' để tìm xem liệu tất cả bản ghi trong con trỏ có được tìm nạp hay không. Nếu được tìm nạp thì nó sẽ trả về 'TRUE' và điều khiển sẽ thoát khỏi vòng lặp, nếu không điều khiển sẽ tiếp tục tìm nạp dữ liệu từ con trỏ và in dữ liệu.
- Dòng mã 11: Điều kiện EXIT cho câu lệnh vòng lặp.
- Dòng mã 12: In tên nhân viên được tìm nạp.
- Dòng mã 14: Sử dụng thuộc tính con trỏ '%ROWCOUNT' để tìm tổng số bản ghi bị ảnh hưởng/tìm nạp trong con trỏ.
- Dòng mã 15: Sau khi thoát khỏi vòng lặp, con trỏ sẽ đóng lại và bộ nhớ được cấp phát sẽ được giải phóng.
Câu lệnh con trỏ vòng lặp FOR
Câu lệnh “FOR LOOP” có thể được sử dụng để làm việc với con trỏ. Chúng ta có thể đặt tên con trỏ thay vì giới hạn phạm vi trong câu lệnh vòng lặp FOR để vòng lặp hoạt động từ bản ghi đầu tiên của con trỏ đến bản ghi cuối cùng của con trỏ. Biến con trỏ, mở con trỏ, tìm nạp và đóng con trỏ sẽ được thực hiện ngầm bởi vòng lặp FOR.
cú pháp
DECLARE CURSOR <cursor_name> IS <SELECT statement>; BEGIN FOR I IN <cursor_name> LOOP . . END LOOP; END;
- Trong cú pháp trên, phần khai báo chứa phần khai báo của con trỏ.
- Con trỏ được tạo cho câu lệnh 'SELECT' được đưa ra trong phần khai báo con trỏ.
- Trong phần thực thi, con trỏ được khai báo được thiết lập trong vòng lặp FOR và biến vòng lặp 'I' sẽ hoạt động như biến con trỏ trong trường hợp này.
Oracle Ví dụ về con trỏ vòng lặp:
Trong ví dụ này, chúng ta sẽ chiếu tất cả tên nhân viên từ bảng emp bằng vòng lặp con trỏ-FOR.
DECLARE CURSOR guru99_det IS SELECT emp_name FROM emp; BEGIN FOR lv_emp_name IN guru99_det LOOP Dbms_output.put_line(‘Employee Fetched:‘||lv_emp_name.emp_name); END LOOP; END; /
Đầu ra
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY
Giải thích mã
- Dòng mã 2: Khai báo con trỏ guru99_det cho câu lệnh 'SELECT emp_name FROM emp'.
- Dòng mã 4: Xây dựng vòng lặp 'FOR' cho con trỏ có biến vòng lặp lv_emp_name.
- Dòng mã 5: In tên nhân viên trong mỗi lần lặp của vòng lặp.
- Dòng mã 8: Thoát khỏi vòng lặp
Lưu ý: Trong vòng lặp Cursor-FOR, các thuộc tính con trỏ không thể được sử dụng do việc mở, tìm nạp và đóng con trỏ được thực hiện ngầm bởi vòng lặp FOR.