游標
游標是MySQL中一種重要的數據庫操作機制,它解決了SQL集合操作與逐行處理之間的矛盾。這個相信大家基本上都怎么使用過,這個都是建立在使用存儲過程的基礎上的。我們都知道SQL都是批量處理的也就是面向集合操作(一次操作多行),而有些使用場景需要一行一行的處理這個時候就可以用到我們的游標了,當然我們一般情況下還是使用Java代碼分組分配處理的哈哈。因為對應小項目而言使用存儲過程還是太麻煩和太復雜了。
#游標的聲明
DECLARE cursor_name CURSOR FOR select_statement;
DECLARE emp_cursor CURSOR FOR -實例SELECT id, name, salary FROM employees WHERE department = 'IT';#打開游標
OPEN cursor_name;
OPEN emp_cursor; -實例#獲取數據
FETCH cursor_name INTO var1, var2, ...;
DECLARE emp_id INT; -實例
DECLARE emp_name VARCHAR(50);
DECLARE emp_salary DECIMAL(10,2);
FETCH emp_cursor INTO emp_id, emp_name, emp_salary;#關閉游標
CLOSE cursor_name;
CLOSE emp_cursor; -實例#基礎使用
DELIMITER //
CREATE PROCEDURE process_employees()
BEGINDECLARE done INT DEFAULT FALSE;DECLARE e_id INT;DECLARE e_name VARCHAR(100);DECLARE e_salary DECIMAL(10,2);-- 聲明游標DECLARE emp_cursor CURSOR FOR SELECT employee_id, name, salary FROM employees WHERE status = 'active';-- 聲明異常處理器DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;OPEN emp_cursor;read_loop: LOOPFETCH emp_cursor INTO e_id, e_name, e_salary;IF done THENLEAVE read_loop;END IF;-- 業務處理:薪資超過1萬加10%獎金IF e_salary > 10000 THENINSERT INTO bonuses(employee_id, amount) VALUES (e_id, e_salary * 0.10);END IF;END LOOP;CLOSE emp_cursor;
END //
DELIMITER ;
其實游標理解起來也很簡單,就是Mysql自己的迭代器,對每一行進行精細的處理,當然這樣的話速度肯定不夠原來的sql快的。
觸發器
觸發器(Trigger)是MySQL中的一種特殊存儲過程,它會在特定的數據庫事件發生時自動執行。觸發器與表緊密關聯,這個其實和我們Java中的監聽器是一個道理,監聽某一種行為如何做某件事,而Mysql的觸發器也是一樣的不需要顯示的調用就可以執行功能的。
觸發時機 | 數據操作 | 說明 |
---|---|---|
BEFORE | INSERT | 插入數據前觸發 |
AFTER | INSERT | 插入數據后觸發 |
BEFORE | UPDATE | 更新數據前觸發 |
AFTER | UPDATE | 更新數據后觸發 |
BEFORE | DELETE | 刪除數據前觸發 |
AFTER | DELETE | 刪除數據后觸發 |
DELIMITER //
CREATE TRIGGER trigger_name
{BEFORE | AFTER} {INSERT | UPDATE | DELETE}
ON table_name FOR EACH ROW
[trigger_order]
trigger_body
DELIMITER ;
這個就是觸發器的語法結構,其實和存儲過程的結構是類似的,只是關鍵詞不一樣。
變量 | 說明 | 可用時機 |
---|---|---|
NEW.column | 新數據值 | INSERT/UPDATE |
OLD.column | 原數據值 | UPDATE/DELETE |
-- 示例:記錄員工薪資變更歷史
DELIMITER //
CREATE TRIGGER log_salary_changes
AFTER UPDATE ON employees
FOR EACH ROW
BEGINIF OLD.salary != NEW.salary THENINSERT INTO salary_audit(employee_id, old_salary, new_salary, change_time) VALUES (NEW.id, OLD.salary, NEW.salary, NOW());END IF;
END //
DELIMITER ;
這個其實也是比較簡單的,大家看看也都會這么寫了,但是一般沒有什么使用的場景,因為寫到Java項目里代碼可讀性和日志查詢要比mysql看起來是更加的直觀的。
#查特定數據庫的觸發器
SHOW TRIGGERS FROM database_name;
-- 或
SHOW TRIGGERS LIKE 'pattern%'; -- 使用通配符#查某個表的觸發器
SHOW TRIGGERS WHERE `Table` = 'table_name';#獲取觸發器sql
SHOW CREATE TRIGGER trigger_name;
總結
本篇主要講了Mysql中的游標和觸發器的作用和使用場景。