MySQL cho phép một Stored Procedure gọi các Stored Procedure khác bên trong thân hàm (nested calls). Điều này giúp mô-đun hóa logic, tái sử dụng code, và xây dựng quy trình nghiệp vụ phức tạp từ các đơn vị nhỏ.
Cú pháp tổng quát
DELIMITER //
CREATE PROCEDURE MainProcedure()
BEGIN
CALL SubProcedure1();
CALL SubProcedure2();
-- ...
CALL SubProcedureN();
END //
DELIMITER ;
Ví dụ minh họa hoàn chỉnh
1. Tạo procedure con thứ 1
mysql> DELIMITER //
mysql> CREATE PROCEDURE hello_message()
BEGIN
SELECT 'HELLO WORLD !!';
END //
Query OK, 0 rows affected (0.19 sec)
2. Tạo procedure con thứ 2
mysql> CREATE PROCEDURE hi_message()
BEGIN
SELECT 'HI !!!!';
END //
Query OK, 0 rows affected (0.11 sec)
mysql> DELIMITER ;
3. Tạo procedure chính gọi 2 procedure con
mysql> DELIMITER //
mysql> CREATE PROCEDURE call_all_stored_procedure()
BEGIN
CALL hello_message();
CALL hi_message();
END //
Query OK, 0 rows affected (0.26 sec)
mysql> DELIMITER ;
4. Gọi procedure chính
mysql> CALL call_all_stored_procedure();
Kết quả (2 result set riêng biệt):
+----------------+ | HELLO WORLD !! | +----------------+ | HELLO WORLD !! | +----------------+ 1 row in set (0.06 sec) +---------+ | HI !!!! | +---------+ | HI !!!! | +---------+ 1 row in set (0.06 sec) Query OK, 0 rows affected (0.08 sec)
Điều khiển luồng (Control Flow) trong Procedure
Có thể kết hợp IF, CASE, LOOP, WHILE để gọi có điều kiện:
CREATE PROCEDURE process_orders(IN p_status VARCHAR(20))
BEGIN
IF p_status = 'new' THEN
CALL process_new_orders();
ELSEIF p_status = 'pending' THEN
CALL process_pending_orders();
ELSE
CALL process_other_orders();
END IF;
CALL log_processing_activity(p_status);
END;
Lưu ý quan trọng
- DELIMITER: Phải đổi delimiter (thường là
//) trước khi tạo procedure để MySQL không nhầm dấu;bên trong body. - Quyền: User cần quyền
CREATE ROUTINEvàEXECUTE. - Transaction: Mặc định mỗi CALL chạy trong transaction riêng. Để gom transaction, dùng
START TRANSACTIONở procedure cha (nếu engine hỗ trợ). - Đệ quy: MySQL cho phép procedure tự gọi chính nó (recursive) nhưng cần cấu hình
max_sp_recursion_depth> 0. - Result set: Mỗi
CALLtrả về result set riêng — ứng dụng client phải xử lý multiple result sets.