Trong SQL, con trỏ đóng vai trò như một con trỏ cho phép ngôn ngữ lập trình ứng dụng xử lý từng hàng một với kết quả truy vấn. Bài viết này nhanh chóng khám phá khái niệm đằng sau và chỉ ra cách khai báo con trỏ, mở, truy xuất dữ liệu từ chúng và sau đó đóng chúng.
Con trỏ SQL
Dữ liệu trong cơ sở dữ liệu quan hệ được quản lý dưới dạng tập hợp. Do đó, kết quả truy vấn trả về bởi câu lệnh SQL SELECT được gọi là tập kết quả. Các tập hợp kết quả không là gì ngoài sự kết hợp của một hoặc nhiều hàng và cột được trích xuất từ một hoặc nhiều bảng. Bạn có thể cuộn qua các tập hợp kết quả để trích xuất thông tin bạn cần. Các phần tử dữ liệu trả về được sử dụng bởi các ngôn ngữ lập trình như Java hoặc bất kỳ ngôn ngữ nào khác cho các mục đích ứng dụng cụ thể. Nhưng ở đây nằm ở vấn đề không khớp trở kháng do sự khác biệt về cấu trúc giữa mô hình cơ sở dữ liệu và mô hình ngôn ngữ lập trình.
Mô hình cơ sở dữ liệu SQL có ba cấu trúc chính:
- cột (hoặc thuộc tính) và kiểu dữ liệu của chúng
- hàng (bản ghi hoặc bộ giá trị)
- bảng (tập hợp các bản ghi)
Do đó, sự không khớp chính giữa hai mô hình là:
- Các kiểu dữ liệu thuộc tính có sẵn trong mô hình cơ sở dữ liệu không giống với các kiểu biến được sử dụng trong ngôn ngữ lập trình. Có nhiều ngôn ngữ máy chủ và mỗi ngôn ngữ có một kiểu dữ liệu khác nhau. Ví dụ, kiểu dữ liệu của C / C ++ và Java là khác nhau và kiểu dữ liệu SQL cũng vậy. Do đó, cần có cơ chế ràng buộc để giảm thiểu vấn đề không tương thích.
- Kết quả trả về bởi câu lệnh SQL SELECT là nhiều bộ bản ghi trong đó mỗi bản ghi là một tập hợp các thuộc tính. Các ngôn ngữ lập trình máy chủ thường hoạt động trên các giá trị dữ liệu riêng lẻ của bộ tuple do truy vấn trả về. Do đó, điều cần thiết là ánh xạ kết quả truy vấn SQL với cấu trúc dữ liệu được hỗ trợ bởi ngôn ngữ lập trình. Cơ chế lặp qua các bộ giá trị là cần thiết để lặp lại các bộ giá trị và giá trị thuộc tính của chúng.
Con trỏ hoạt động giống như một biến trình lặp để lặp qua các bộ do truy vấn SQL trả về và trích xuất các giá trị riêng lẻ trong mỗi bộ, sau đó có thể được ánh xạ tới loại biến chương trình thích hợp.
Do đó, con trỏ đóng vai trò như một con trỏ cho phép ngôn ngữ lập trình xử lý từng bản ghi kết quả truy vấn. Con trỏ có thể duyệt qua tất cả các hàng của kết quả truy vấn tập trung vào một hàng tại một thời điểm. Hãy xem xét truy vấn SQL sau:
SELECT emp_no, first_name, last_name, birth_date FROM employees WHERE MONTH(birth_date) = MONTH(CURRENT_DATE) AND DAY(birth_date) = DAY(CURRENT_DATE);
Kết quả truy vấn từ câu lệnh trên trả về chi tiết nhân viên của tất cả những nhân viên có ngày sinh rơi vào ngày hiện tại của một tháng cụ thể. Kết quả có thể chứa nhiều hàng, nhưng ngôn ngữ ứng dụng lưu trữ có thể xử lý từng hàng một. Do đó, con trỏ được khai báo như một câu lệnh SQL nhúng trong ngôn ngữ lập trình ứng dụng. Sau đó, con trỏ được mở giống như một tệp và trích xuất một hàng từ kết quả truy vấn. Các hàng khác được trích xuất sau đó, theo trình tự cho đến khi đóng con trỏ.
Khai báo con trỏ
Con trỏ được khai báo giống như một biến. Tên được đưa ra, có các câu lệnh để mở con trỏ, truy xuất kết quả truy vấn và cuối cùng là đóng con trỏ. Lưu ý rằng, các triển khai SQL khác nhau hỗ trợ việc sử dụng con trỏ theo một cách khác. Nhưng có một thỏa thuận chung về cách viết con trỏ.
Chúng ta phải sử dụng các câu lệnh SQL để thực hiện đầy đủ chức năng của con trỏ vì chỉ khai báo một con trỏ là không đủ để trích xuất dữ liệu từ cơ sở dữ liệu SQL. Có bốn bước cơ bản để khai báo một con trỏ:
NHÂN VIÊN KHAI BÁO: Khai báo bắt đầu bằng cách đặt tên cho con trỏ và gán biểu thức truy vấn sẽ được gọi khi con trỏ được mở.
MỞ: Câu lệnh mở thực thi biểu thức truy vấn được chỉ định và tạo kết quả truy vấn sẵn sàng cho FETCH tiếp theo.
TÌM HIỂU: Truy xuất các giá trị dữ liệu vào các biến mà sau đó có thể được chuyển sang ngôn ngữ lập trình máy chủ hoặc sang các câu lệnh SQL nhúng khác.
ĐÓNG: Con trỏ bị đóng không cho tìm nạp thêm bất kỳ kết quả truy vấn nào.
Cú pháp như sau:
DECLARE <cursor_name> [SENSITIVE | INSENSITIVE | ASENSITIVE] [SCROLL | NO SCROLL] CURSOR [ WITH HOLD | WITHOUT HOLD] [ WITH RETURN | WITHOUT RETURN] FOR <sql_query_expression> [ ORDER BY <sort_expression>] [ FOR {READ ONLY | UPDATE [ OF <list_of_column>]}]
Phần thiết yếu của khai báo con trỏ như sau:
DECLARE <cursor_name> FOR <sql_query_expression>
Phần tùy chọn chẳng hạn như [SENSITIVE | NHẠY CẢM | ASENSITIVE] cho biết liệu con trỏ có nhạy cảm với các thay đổi hay không và có phản ánh chúng trong kết quả truy vấn hay không. SENSITIVE có nghĩa là con trỏ bị ảnh hưởng bởi các thay đổi, INSENSITIVE có nghĩa là con trỏ không bị ảnh hưởng và ASENSITIVE có nghĩa là các thay đổi có thể hiển thị hoặc có thể không hiển thị đối với con trỏ. Nếu không được chỉ định, nó sẽ giả sử tùy chọn ASENSITIVE.
Tùy chọn [SCROLL | NOSCROLL] xác định khả năng cuộn của con trỏ. Nếu không được chỉ định, nó sẽ giả sử tùy chọn KHÔNG CUỘC SỐ.
Tùy chọn [CÓ GIỮ | KHÔNG GIỮ ĐƯỢC] xác định việc giữ hoặc tự động đóng khi giao dịch do con trỏ được cam kết. Nếu không được chỉ định, nó sẽ duy trì tùy chọn KHÔNG GIỮ.
Tùy chọn [CÓ QUAY LẠI | KHÔNG CÓ TRẢ LẠI] xác định xem có trả lại kết quả con trỏ được đặt cho lệnh gọi, chẳng hạn như quy trình SQL khác hoặc ngôn ngữ máy chủ hay không. Nếu không được chỉ định nghĩa là KHÔNG CÓ TRẢ LẠI.
Mệnh đề ORDER BY được sử dụng để sắp xếp kết quả truy vấn được trả về theo kỹ thuật sắp xếp đã chỉ định.
Tùy chọn UPDATE đề cập đến việc sử dụng câu lệnh UPDATE hoặc DELETE được liên kết với các hàng được trả về bởi câu lệnh SELECT của con trỏ. Bất kỳ sửa đổi nào như vậy đều không thể thực hiện được nếu chúng tôi chỉ định tùy chọn CHỈ ĐỌC. Nếu không được chỉ định, thì tùy chọn UPDATE theo mặc định sẽ được giả định.
Do đó, một con trỏ đơn giản có thể được khai báo như sau:
DECLARE mycursor CURSOR FOR SELECT emp_no, first_name, last_name, birth_date FROM employees WHERE MONTH(birth_date) = MONTH(CURRENT_DATE) AND DAY(birth_date) = DAY(CURRENT_DATE);
Con trỏ trong MySQL
Thông thường, có hai loại con trỏ được tìm thấy trong MySQL:con trỏ chỉ đọc và chỉ chuyển tiếp. Các con trỏ này có thể được sử dụng cho thủ tục lưu trữ MySQL. Các con trỏ này giúp chúng tôi lặp lại từng hàng một trong các kết quả truy vấn và tìm nạp vào các biến để xử lý thêm. Có thể khai báo nhiều hơn một con trỏ và lồng chúng trong các vòng lặp. Lưu ý rằng con trỏ ở chế độ chỉ đọc vì chúng được sử dụng để lặp qua các bảng tạm thời. Con trỏ thường thực hiện truy vấn khi chúng ta mở nó.
Một trong những vấn đề với con trỏ trong MySQL là chúng có thể làm chậm hiệu suất của truy vấn do các hoạt động I / O bổ sung mà chúng thực hiện. Điều này đặc biệt dành cho các kiểu dữ liệu lớn thực sự như BLOB và TEXT. Vì con trỏ hoạt động với các bảng tạm thời, các loại này không được hỗ trợ trong các bảng trong bộ nhớ. Do đó, trong khi làm việc với các kiểu này, MySQL phải tạo các bảng tạm thời trên đĩa và điều đó đòi hỏi nhiều thao tác I / O và điều đó cũng xảy ra trong các thiết bị chậm như đĩa. Đây là lý do chính khiến con trỏ hoạt động chậm.
MySQL cũng không hỗ trợ con trỏ phía máy khách tuy nhiên API máy khách có thể mô phỏng chúng nếu cần thiết. Nhưng sau đó, điều này không khác nhiều so với việc tìm nạp kết quả trong một mảng bằng ngôn ngữ lập trình như Java và thay vào đó thao tác chúng ở đó.
Đây là ví dụ về cách viết con trỏ trong MySQL.
CREATE PROCEDURE 'cursor_demo'() BEGIN DECLARE done INT DEFAULT FALSE; DECLARE id INT(11); DECLARE fn varchar(14); DECLARE ln varchar(16); DECLARE bdate date; DECLARE mycursor CURSOR FOR SELECT emp_no, first_name, last_name, birth_date FROM employees WHERE MONTH(birth_date)=MONTH(CURRENT_DATE) AND DAY(birth_date)=DAY(CURRENT_DATE); DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN mycursor; fetch_loop: LOOP FETCH mycursor INTO id, fn, ln, bdate; IF done THEN LEAVE fetch_loop; END IF; SELECT id, fn, ln, bdate; END LOOP; CLOSE mycursor; END
Gọi thủ tục được lưu trữ như sau:
mysql> CALL cursor_demo
Thủ tục tìm nạp các hàng từ một bảng có tên nhân viên có ngày sinh khớp với ngày và tháng hiện tại trong con trỏ có tên là mycursor và chỉ cần in chúng bằng câu lệnh SELECT.
Tham khảo Tài liệu MySQL về Con trỏ để biết thêm thông tin.
Kết luận
Con trỏ không là gì khác ngoài con trỏ đến các tập hợp bản ghi được trả về bởi truy vấn SQL. Con trỏ thường trỏ đến một hàng tại một thời điểm và có thể được duyệt trong một vòng lặp để truy xuất các bản ghi riêng lẻ. SQL thường được sử dụng để gọi trực tiếp để truy cập và tạo các đối tượng dữ liệu. Các con trỏ cung cấp kỹ thuật SQL tương tác trong đó nó cho phép thực thi đặc biệt các câu lệnh SQL được hỗ trợ thông qua ứng dụng khách. Cơ chế của con trỏ thúc đẩy mô hình truy cập dữ liệu trong đó các câu lệnh SQL được nhúng trong ngôn ngữ máy chủ như C, C ++ hoặc Java, v.v. Đây chỉ là một cái nhìn thoáng qua về những gì con trỏ sắp bắt đầu. Tham khảo tài liệu cơ sở dữ liệu SQL thích hợp để biết chi tiết về các tiêu chuẩn cụ thể của việc triển khai khác nhau.
# # #