Tóm lược. trong hướng dẫn này, bạn sẽ học cách sử dụng trình xử lý MySQL để xử lý các lỗi gặp phải trong thủ tục lưu trữ
Khi xảy ra lỗi bên trong một thủ tục được lưu trữ, điều quan trọng là phải xử lý nó một cách thích hợp, chẳng hạn như tiếp tục hoặc thoát khỏi quá trình thực thi khối mã hiện tại và đưa ra một thông báo lỗi có ý nghĩa
MySQL cung cấp một cách dễ dàng để định nghĩa các trình xử lý xử lý từ các điều kiện chung như cảnh báo hoặc ngoại lệ đến các điều kiện cụ thể e. g. , mã lỗi cụ thể
Khai báo một handler
Để khai báo một trình xử lý, bạn sử dụng câu lệnh
2 như sauCode language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
Code language: SQL [Structured Query Language] [sql]
DECLARE action HANDLER FOR condition_value statement;
Nếu một điều kiện có giá trị khớp với
3 , MySQL sẽ thực thiCode language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
4 và tiếp tục hoặc thoát khỏi khối mã hiện tại dựa trênCode language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
5Code language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
5 chấp nhận một trong các giá trị sauCode language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
7. việc thực thi khối mã kèm theo [
Code language: SQL [Structured Query Language] [sql]DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
8 …
Code language: SQL [Structured Query Language] [sql]DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
9 ] vẫn tiếp tục
Code language: SQL [Structured Query Language] [sql]DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
0. việc thực thi khối mã kèm theo, nơi trình xử lý được khai báo, chấm dứt
Code language: SQL [Structured Query Language] [sql]DECLARE CONTINUE HANDLER FOR NOT FOUND SET RowNotFound = 1;
3 chỉ định một điều kiện cụ thể hoặc một nhóm điều kiện kích hoạt trình xử lý.Code language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
3 chấp nhận một trong các giá trị sauCode language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
- Mã lỗi MySQL
- Một giá trị
3 tiêu chuẩn. Hoặc nó có thể là một điều kiện
Code language: SQL [Structured Query Language] [sql]DECLARE CONTINUE HANDLER FOR NOT FOUND SET RowNotFound = 1;
4 ,
Code language: SQL [Structured Query Language] [sql]DECLARE CONTINUE HANDLER FOR NOT FOUND SET RowNotFound = 1;
5 hoặc
Code language: SQL [Structured Query Language] [sql]DECLARE CONTINUE HANDLER FOR NOT FOUND SET RowNotFound = 1;
6, là cách viết tắt của loại giá trị
Code language: SQL [Structured Query Language] [sql]DECLARE CONTINUE HANDLER FOR NOT FOUND SET RowNotFound = 1;
3. Điều kiện
Code language: SQL [Structured Query Language] [sql]DECLARE CONTINUE HANDLER FOR NOT FOUND SET RowNotFound = 1;
5 được sử dụng cho một con trỏ hoặc câu lệnh
Code language: SQL [Structured Query Language] [sql]DECLARE CONTINUE HANDLER FOR NOT FOUND SET RowNotFound = 1;
9
Code language: SQL [Structured Query Language] [sql]DECLARE CONTINUE HANDLER FOR NOT FOUND SET RowNotFound = 1;
- Một điều kiện được đặt tên liên quan đến mã lỗi MySQL hoặc giá trị
3
Code language: SQL [Structured Query Language] [sql]DECLARE CONTINUE HANDLER FOR NOT FOUND SET RowNotFound = 1;
4 có thể là một mệnh đề đơn giản hoặc một mệnh đề ghép bao quanh bởi các từ khóaCode language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
8 vàCode language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
9
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
Code language: SQL [Structured Query Language] [sql]
Ví dụ xử lý lỗi MySQL
Hãy lấy một số ví dụ về khai báo trình xử lý
Trình xử lý sau đây đặt giá trị của biến
4 thành 1 và tiếp tục thực thi nếu xảy raCode language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR 1062 SELECT 'Error, duplicate key occurred';
6Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR NOT FOUND SET RowNotFound = 1;
Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET hasError = 1;
Trình xử lý sau khôi phục các hoạt động trước đó, đưa ra thông báo lỗi và thoát khỏi khối mã hiện tại trong trường hợp xảy ra lỗi. Nếu bạn khai báo nó bên trong khối
6 của thủ tục được lưu trữ, nó sẽ chấm dứt thủ tục được lưu trữ ngay lập tứcCode language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR 1062 SELECT 'Error, duplicate key occurred';
Code language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
Trình xử lý sau đặt giá trị của biến
7 thành 1 và tiếp tục thực thi nếu không còn hàng để tìm nạp trong trường hợp con trỏ hoặc câu lệnhCode language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR 1062 SELECT 'Error, duplicate key occurred';
8Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR 1062 SELECT 'Error, duplicate key occurred';
Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR NOT FOUND SET RowNotFound = 1;
Nếu xảy ra lỗi khóa trùng lặp, trình xử lý sau sẽ đưa ra thông báo lỗi và tiếp tục thực hiện
Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR 1062 SELECT 'Error, duplicate key occurred';
Ví dụ về trình xử lý MySQL trong thủ tục lưu sẵn
Đầu tiên, tạo một bảng mới có tên là
9để trình diễnCode language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR 1062 SELECT 'Error, duplicate key occurred';
Code language: SQL [Structured Query Language] [sql]
CREATE TABLE SupplierProducts [ supplierId INT, productId INT, PRIMARY KEY [supplierId , productId] ];
Bảng
9 lưu trữ các mối quan hệ giữa các nhà cung cấp và sản phẩm của bảng. Mỗi nhà cung cấp có thể cung cấp nhiều sản phẩm và mỗi sản phẩm có thể được cung cấp bởi nhiều nhà cung cấp. Để đơn giản, chúng tôi không tạo các bảngCode language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR 1062 SELECT 'Error, duplicate key occurred';
1 vàCode language: SQL [Structured Query Language] [sql]
CREATE TABLE SupplierProducts [ supplierId INT, productId INT, PRIMARY KEY [supplierId , productId] ];
2, cũng như các khóa ngoại trong bảngCode language: SQL [Structured Query Language] [sql]
CREATE TABLE SupplierProducts [ supplierId INT, productId INT, PRIMARY KEY [supplierId , productId] ];
9Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR 1062 SELECT 'Error, duplicate key occurred';
Thứ hai, tạo một thủ tục được lưu trữ để chèn id sản phẩm và id nhà cung cấp vào bảng
9Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR 1062 SELECT 'Error, duplicate key occurred';
Code language: SQL [Structured Query Language] [sql]
CREATE PROCEDURE InsertSupplierProduct[ IN inSupplierId INT, IN inProductId INT ] BEGIN -- exit if the duplicate key occurs DECLARE EXIT HANDLER FOR 1062 BEGIN SELECT CONCAT['Duplicate key [',inSupplierId,',',inProductId,'] occurred'] AS message; END; -- insert a new row into the SupplierProducts INSERT INTO SupplierProducts[supplierId,productId] VALUES[inSupplierId,inProductId]; -- return the products supplied by the supplier id SELECT COUNT[*] FROM SupplierProducts WHERE supplierId = inSupplierId; END$$ DELIMITER ;
Làm thế nào nó hoạt động
Trình xử lý thoát sau đây chấm dứt thủ tục được lưu trữ bất cứ khi nào xảy ra khóa trùng lặp [với mã 1062]. Ngoài ra, nó trả về một thông báo lỗi
Code language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR 1062 BEGIN SELECT CONCAT['Duplicate key [',supplierId,',',productId,'] occurred'] AS message; END;
Câu lệnh này chèn một hàng vào bảng
9. Nếu khóa trùng lặp xảy ra, mã trong phần xử lý sẽ thực thi
DECLARE CONTINUE HANDLER FOR 1062 SELECT 'Error, duplicate key occurred';
Code language: SQL [Structured Query Language] [sql]
Code language: SQL [Structured Query Language] [sql]
INSERT INTO SupplierProducts[supplierId,productId] VALUES[supplierId,productId];
Thứ ba, gọi
6 để chèn một số hàng vào bảngCode language: SQL [Structured Query Language] [sql]
CREATE TABLE SupplierProducts [ supplierId INT, productId INT, PRIMARY KEY [supplierId , productId] ];
9Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR 1062 SELECT 'Error, duplicate key occurred';
Code language: SQL [Structured Query Language] [sql]
CALL InsertSupplierProduct[1,1]; CALL InsertSupplierProduct[1,2]; CALL InsertSupplierProduct[1,3];
Thứ tư, cố gắng chèn một hàng có giá trị đã tồn tại trong bảng
9Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR 1062 SELECT 'Error, duplicate key occurred';
0Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET hasError = 1;
Đây là thông báo lỗi
1Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET hasError = 1;
Vì trình xử lý là trình xử lý
0 nên câu lệnh cuối cùng không thực thiCode language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR NOT FOUND SET RowNotFound = 1;
2Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET hasError = 1;
Nếu bạn thay đổi
0 trong phần khai báo của nhà xử lý thànhCode language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR NOT FOUND SET RowNotFound = 1;
7, thì bạn cũng sẽ nhận được số lượng sản phẩm do nhà cung cấp cung cấpCode language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
3Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET hasError = 1;
Cuối cùng, gọi lại thủ tục lưu sẵn để xem tác dụng của trình xử lý
7Code language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
0Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET hasError = 1;
Đây là đầu ra
5Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET hasError = 1;
Ưu tiên xử lý MySQL
Trong trường hợp bạn có nhiều trình xử lý xử lý cùng một lỗi, MySQL sẽ gọi trình xử lý cụ thể nhất để xử lý lỗi trước dựa trên các quy tắc sau
- Một lỗi luôn ánh xạ tới mã lỗi MySQL vì trong MySQL, nó là mã cụ thể nhất
- Một
3 có thể ánh xạ tới nhiều mã lỗi MySQL, do đó, nó ít cụ thể hơn
Code language: SQL [Structured Query Language] [sql]DECLARE CONTINUE HANDLER FOR NOT FOUND SET RowNotFound = 1;
- Một
4 hoặc một
Code language: SQL [Structured Query Language] [sql]CREATE PROCEDURE InsertSupplierProduct[ IN inSupplierId INT, IN inProductId INT ] BEGIN -- exit if the duplicate key occurs DECLARE EXIT HANDLER FOR 1062 BEGIN SELECT CONCAT['Duplicate key [',inSupplierId,',',inProductId,'] occurred'] AS message; END; -- insert a new row into the SupplierProducts INSERT INTO SupplierProducts[supplierId,productId] VALUES[inSupplierId,inProductId]; -- return the products supplied by the supplier id SELECT COUNT[*] FROM SupplierProducts WHERE supplierId = inSupplierId; END$$ DELIMITER ;
4 là cách viết tắt của một lớp gồm các giá trị
Code language: SQL [Structured Query Language] [sql]DECLARE CONTINUE HANDLER FOR NOT FOUND SET RowNotFound = 1;
6 vì vậy nó là loại chung nhất
Code language: SQL [Structured Query Language] [sql]CREATE PROCEDURE InsertSupplierProduct[ IN inSupplierId INT, IN inProductId INT ] BEGIN -- exit if the duplicate key occurs DECLARE EXIT HANDLER FOR 1062 BEGIN SELECT CONCAT['Duplicate key [',inSupplierId,',',inProductId,'] occurred'] AS message; END; -- insert a new row into the SupplierProducts INSERT INTO SupplierProducts[supplierId,productId] VALUES[inSupplierId,inProductId]; -- return the products supplied by the supplier id SELECT COUNT[*] FROM SupplierProducts WHERE supplierId = inSupplierId; END$$ DELIMITER ;
Dựa trên các quy tắc về mức độ ưu tiên của trình xử lý, trình xử lý mã lỗi MySQL, trình xử lý
3 vàCode language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR NOT FOUND SET RowNotFound = 1;
6 có mức độ ưu tiên thứ nhất, thứ hai và thứ ba
DECLARE CONTINUE HANDLER FOR NOT FOUND SET RowNotFound = 1;
Code language: SQL [Structured Query Language] [sql]
Giả sử rằng chúng ta có ba trình xử lý trong các trình xử lý trong thủ tục lưu sẵn
9Code language: SQL [Structured Query Language] [sql]
CREATE PROCEDURE InsertSupplierProduct[ IN inSupplierId INT, IN inProductId INT ] BEGIN -- exit if the duplicate key occurs DECLARE EXIT HANDLER FOR 1062 BEGIN SELECT CONCAT['Duplicate key [',inSupplierId,',',inProductId,'] occurred'] AS message; END; -- insert a new row into the SupplierProducts INSERT INTO SupplierProducts[supplierId,productId] VALUES[inSupplierId,inProductId]; -- return the products supplied by the supplier id SELECT COUNT[*] FROM SupplierProducts WHERE supplierId = inSupplierId; END$$ DELIMITER ;
6Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET hasError = 1;
Gọi thủ tục được lưu trữ để chèn khóa trùng lặp
0Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET hasError = 1;
Đây là đầu ra
8Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET hasError = 1;
Như bạn thấy trình xử lý mã lỗi MySQL được gọi là
Sử dụng một điều kiện lỗi được đặt tên
Hãy bắt đầu với một khai báo trình xử lý lỗi
9Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET hasError = 1;
Số
0 thực sự có ý nghĩa gì?Code language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR 1062 BEGIN SELECT CONCAT['Duplicate key [',supplierId,',',productId,'] occurred'] AS message; END;
May mắn thay, MySQL cung cấp cho bạn câu lệnh
1 tuyên bố một điều kiện lỗi được đặt tên, kết hợp với một điều kiệnCode language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR 1062 BEGIN SELECT CONCAT['Duplicate key [',supplierId,',',productId,'] occurred'] AS message; END;
Đây là cú pháp của câu lệnh
1Code language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR 1062 BEGIN SELECT CONCAT['Duplicate key [',supplierId,',',productId,'] occurred'] AS message; END;
0Code language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
3 có thể là mã lỗi MySQL chẳng hạn nhưCode language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
0 hoặc giá trịCode language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR 1062 BEGIN SELECT CONCAT['Duplicate key [',supplierId,',',productId,'] occurred'] AS message; END;
3.Code language: SQL [Structured Query Language] [sql]
DECLARE CONTINUE HANDLER FOR NOT FOUND SET RowNotFound = 1;
3 được đại diện bởiCode language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
7Code language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR 1062 BEGIN SELECT CONCAT['Duplicate key [',supplierId,',',productId,'] occurred'] AS message; END;
Sau khi khai báo, bạn có thể tham khảo
7 thay vìCode language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR 1062 BEGIN SELECT CONCAT['Duplicate key [',supplierId,',',productId,'] occurred'] AS message; END;
3Code language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
Vì vậy, bạn có thể viết lại đoạn mã trên như sau
1Code language: SQL [Structured Query Language] [sql]
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 'An error has occurred, operation rollbacked and the stored procedure was terminated'; END;
Như bạn có thể thấy, mã này rõ ràng và dễ đọc hơn mã trước đó. Lưu ý rằng khai báo điều kiện phải xuất hiện trước khai báo bộ xử lý hoặc con trỏ
Trong hướng dẫn này, bạn đã học cách sử dụng trình xử lý MySQL để xử lý ngoại lệ hoặc lỗi xảy ra trong thủ tục lưu trữ