前面實作練習使用了Trigger、Stored Procedure、Stored Function來完成訂單的處理,但是在處理的過程中沒有加入「錯誤處理」,也就是當發生錯誤時應該怎麼處理。
在資料庫操作中,錯誤處理是一個非常重要的部分,它確保當操作失敗或發生異常時,系統能夠優雅地應對並保護資料完整性和一致性。錯誤處理的主要目的是識別錯誤、記錄錯誤資訊、進行必要的補救措施(如Rollback),並將錯誤訊息適當地傳達給使用者或系統管理員。
錯誤處理的語法 :
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
-- 錯誤處理程序
-- 這裡加入需要的邏輯
END;
(1) Stored Procedure處理錯誤 :
-- 建立一個資料表Products :
CREATE TABLE Products (
ProductID INT AUTO_INCREMENT PRIMARY KEY,
ProductName VARCHAR(100) NOT NULL,
Price DECIMAL(10, 2) NOT NULL,
Stock INT NOT NULL
);
-- 建立一個資料表ProductLogs :
CREATE TABLE ProductLogs (
LogID INT AUTO_INCREMENT PRIMARY KEY,
ActionDateTime DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
Action VARCHAR(255)
);
再建立Stored Procedure :
DELIMITER //
CREATE PROCEDURE CreateProduct(
IN p_Name VARCHAR(100),
IN p_Price DECIMAL(10, 2),
IN p_Stock INT
)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
-- 錯誤處理:回滾事務並記錄錯誤訊息
ROLLBACK;
-- 插入日誌
INSERT INTO ProductLogs (Action) VALUES ('INSERT Problem');
END;
-- 開始事務
START TRANSACTION;
-- 插入產品
INSERT INTO Products (ProductName, Price, Stock) VALUES (p_Name, p_Price, p_Stock);
-- 提交事務
COMMIT;
END //
DELIMITER ;
呼叫 Call CreateProduct('Product d', 100.00, 50);
當INSERT INTO products 發生錯誤,就會進入錯誤處理
(例如把Products表格欄位改一下,故意讓他無法插入資料)
但是如果INSERT INTO productLogs又發生錯誤呢? 需要再修改如下 :
DELIMITER //
CREATE PROCEDURE CreateProduct(
IN p_Name VARCHAR(100),
IN p_Price DECIMAL(10, 2),
IN p_Stock INT
)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
-- 二次錯誤處理:防止插入日誌失敗
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
-- 錯誤訊息的其他處理方法,比如記錄到一個系統日誌表,或是僅記錄一個簡單的錯誤訊息
-- 這裡我們只是顯示錯誤訊息,不進行其他操作
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Both product insertion and log insertion failed.';
END;
-- 錯誤處理:回滾事務並記錄錯誤訊息
ROLLBACK;
-- 插入日誌
INSERT INTO ProductLogs (Action) VALUES ('INSERT Problem');
END;
-- 開始事務
START TRANSACTION;
-- 插入產品
INSERT INTO Products (ProductName, Price, Stock) VALUES (p_Name, p_Price, p_Stock);
-- 提交事務
COMMIT;
END //
DELIMITER ;
同樣把ProductLogs表格欄位改一下,故意讓他無法插入資料
INSERT INTO ProductLogs (Action) VALUES ('GetProductPrice Problem');
id INT AUTO_INCREMENT PRIMARY KEY,
column1 INT NOT NULL );
id INT AUTO_INCREMENT PRIMARY KEY,
some_column INT NOT NULL
);
INSERT INTO another_table (some_column) VALUES (10);
INSERT INTO another_table (some_column) VALUES (-5);
0 留言