游标
游标是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中的游标和触发器的作用和使用场景。