Ở bài hôm nay chúng ta cùng tiếp tục tìm hiểu phần kiến thức nâng cao để ứng biến xử lý trong các trường hợp đặc biệt khi xử lý dữ liệu. Đó là CURSOR.
Nội dung
1. CURSOR trong SQL là gì?
CURSOR hay còn gọi là con trỏ, là khái niệm giúp bạn truy cập từng dòng dữ liệu trong quá trình xử lý. Tức là với việc không thể sử dụng các khái niệm mình đã giới thiệu ở các bài vừa qua để giải quyết vấn đề, thì mới nghĩ đến CURSOR.
Khái niệm CURSOR trong SQL
2. Tại sao phải sử dụng CURSOR
Nó dùng để duyệt các record ở table hay ở các kết quả từ câu lệnh truy vấn.
Gồm 3 tính chất sau:
- Read only: chúng ta không thể cập nhật dữ liệu ở table qua CURSOR.
- Non scrollable: chỉ có thể duyệt qua các dòng theo thứ tự được lấy ra từ câu lệnh SELECT. Không thể duyệt theo thứ tự ngược lại. Thêm nữa, chúng ta không thể bỏ qua record hay nhảy đến record mong muốn được.
- Asensitive/Insensitive: có 2 loại CURSOR. Với asensitive thì nó sẽ duyệt trên chính dữ liệu ở table, còn insensitive nó sẽ duyệt trên dữ liệu tạm, tức là dữ liệu được sao chép từ dữ liệu thật. Vì vậy, hiệu suất của asensitive sẽ nhanh hơn insensitive. Tuy nhiên, với bất kỳ sự thay đổi của data chính sẽ làm ảnh hưởng đến quá trình xử lý của asensitive, sẽ an toàn hơn nếu không có sự cập nhật nào về dữ liệu. Loại con trỏ ở MySQL là asensitive.
3. Hướng dẫn cách dùng CURSOR
Cú pháp
- Để khai báo một con trỏ, ta dùng lệnh:
DECLARE cursor_name CURSOR FOR query;
- Khởi tạo kết quả truy vấn để bắt đầu duyệt:
OPEN cursor_name;
- Để lấy kết quả từ con trỏ đến biến:
FETCH cursor_name INTO variables list;
- Dừng hoạt động và giải phóng bộ nhớ con trỏ:
CLOSE cursor_name;
Ví dụ
Để thực hiện gửi tin nhắn đến cho toàn bộ tài khoản của các bác sĩ trong hệ thống, mình tạo ra FUNCTION và đang áp dụng CURSOR để lấy ra danh sách tài khoản, theo định dạng:
[tài khoản 1];[tài khoản 2];[tài khoản 3]…
Trong bài toán này, có thể thấy CURSOR có tên là cur_account, đang đại diện cho một tài khoản. Sau đó kết quả sẽ được tổng hợp dần vào biến account_list.
delimiter //
CREATE FUNCTION sp_get_list_account()
RETURNS TEXT
DETERMINISTIC
BEGIN
DECLARE is_last_record BIT DEFAULT 0;
DECLARE account_doctor VARCHAR(30);
DECLARE account_list TEXT DEFAULT "";
DECLARE cur_account CURSOR FOR
SELECT `account` FROM account_system;
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET is_last_record = 1;
OPEN cur_account;
for_each_account: LOOP
FETCH cur_account INTO account_doctor;
IF is_last_record = 1 THEN
LEAVE for_each_account;
END IF;
SET account_list = CONCAT(account_doctor, ";", account_list);
END LOOP for_each_account;
CLOSE cur_account;
RETURN account_list;
END //
delimiter ;
Kết luận
Hơi khá phức tạp phải không? Bạn cứ hiểu thế này, CURSOR nó sẽ duyệt qua từng record được trả về từ câu lệnh truy vấn. Cứ mỗi vòng lặp, CURSOR sẽ nhảy xuống record tiếp theo, cho đến khi nhảy đến hết record cuối cùng thôi. Nếu bạn đã từng thao tác đọc file ở các ngôn ngữ lập trình rồi, thì CURSOR nó cũng gần tương tự như vậy.
Mặc dù khó để hiểu nhưng CURSOR sẽ giúp bạn linh hoạt hơn trong cách sử dụng để xử lý dữ liệu.
0 Lời bình