Trong SQL, cả Function (Hàm) và Procedure (Thủ tục) đều là tập hợp các câu lệnh SQL được lưu trữ và thực thi trên server. Tuy nhiên, chúng có mục đích, khả năng và hạn chế khác biệt quan trọng.
Định nghĩa nhanh
- Function: Tính toán và trả về một giá trị đơn lẻ (scala) hoặc bảng (table-valued function). Dùng trong biểu thức, SELECT, WHERE.
- Procedure: Thực hiện một chuỗi tác vụ (task), có thể thay đổi dữ liệu (DML), không trả về giá trị (chỉ trả về trạng thái thành công/thất bại qua tham số OUT).
Bảng so sánh chi tiết
| # | Tiêu chí | Function | Procedure |
|---|---|---|---|
| 1 | Định nghĩa | Tính kết quả từ đầu vào | Thực hiện tác vụ theo thứ tự |
| 2 | Gọi nhau | Function có thể gọi Procedure | Procedure không thể gọi Function |
| 3 | DML (INSERT/UPDATE/DELETE) | Không được phép | Được phép |
| 4 | Gọi trong SELECT/WHERE | Được phép | Không được phép |
| 5 | Biên dịch | Biên dịch mỗi lần gọi | Biên dịch 1 lần, gọi nhiều lần |
| 6 | Giá trị trả về | Bắt buộc trả về giá trị + điều khiển | Chỉ trả về điều khiển (không giá trị) |
| 7 | TRY-CATCH / Xử lý lỗi | Không hỗ trợ | Hỗ trợ |
| 8 | Trong SELECT | Có thể gọi | Không thể gọi |
| 9 | Transaction tường minh | Không được phép | Được phép (BEGIN TRAN, COMMIT, ROLLBACK) |
Ví dụ minh họa
Function: Tính thuế
CREATE FUNCTION CalculateTax(amount DECIMAL(10,2), rate DECIMAL(5,2)) RETURNS DECIMAL(10,2) DETERMINISTIC RETURN amount * rate / 100; -- Sử dụng trong SELECT SELECT Price, CalculateTax(Price, 10) AS Tax FROM Products;
Procedure: Xử lý đơn hàng
CREATE PROCEDURE ProcessOrder(IN order_id INT, OUT status VARCHAR(20))
BEGIN
DECLARE stock INT;
SELECT Quantity INTO stock FROM Inventory WHERE ProductId = (SELECT ProductId FROM Orders WHERE Id = order_id);
IF stock > 0 THEN
UPDATE Inventory SET Quantity = Quantity - 1 WHERE ProductId = ...;
UPDATE Orders SET Status = 'Processing' WHERE Id = order_id;
SET status = 'SUCCESS';
ELSE
SET status = 'OUT_OF_STOCK';
END IF;
END;
-- Gọi
CALL ProcessOrder(123, @result);
SELECT @result;
Khi nào dùng cái nào?
- Dùng Function khi: Cần tính toán, chuyển đổi dữ liệu, dùng trong SELECT/WHERE/JOIN, logic thuần túy không thay đổi dữ liệu.
- Dùng Procedure khi: Cần INSERT/UPDATE/DELETE, logic nghiệp vụ phức tạp nhiều bước, cần transaction, cần trả về nhiều giá trị qua OUT parameters, cần xử lý lỗi TRY-CATCH.
Lưu ý MySQL: MySQL Function không hỗ trợ DML. SQL Server Function có thể DML trên bảng biến/table variable nhưng không khuyến khích. Oracle Function có thể DML nếu dùng PRAGMA AUTONOMOUS_TRANSACTION.