数据库触发器与存储过程
触发器
触发器前提准备:
创建并使用数据库:
CREATE DATABASE IF NOT EXISTS mydb16_trigger;
USE mydb16_trigger;

创建商品表和订单表:
CREATE TABLE goods ( gid CHAR(8) PRIMARY KEY,name VARCHAR(10),price DECIMAL(8,2),num INT);
CREATE TABLE orders (oid INT PRIMARY KEY AUTO_INCREMENT,gid CHAR(10) NOT NULL,name VARCHAR(10),price DECIMAL(8,2),onum INT,otime DATE);
查询如下图:
商品表

订单表

对商品表插入数据:
INSERT INTO goods VALUES ('A0001', '橡皮', 2.5, 100),('B0001', '小楷本', 2.8, 210),('C0001', '铅笔', 1.2, 120),('D0001', '计算器', 28, 20);
查询如下图:

触发器创建及测试:
创建触发器并测试(订单增加,商品数量同步减少):
DELIMITER //
CREATE TRIGGER after_order_insert
AFTER INSERT ON orders
FOR EACH ROW
BEGINUPDATE goodsSET num = num - NEW.onumWHERE gid = NEW.gid;
END //

(每次创建完成后将结束符号改回为“;”号。语句为:"DELIMITER ;")
测试触发器:
向订单表中插入数据:
INSERT INTO orders(gid, name, price, onum, otime) VALUES('A0001', '橡皮', 2.5, 10, '2025-11-11');


插入前的商品数量 插入后的商品数量
创建触发器并测试(取消订单时恢复商品数量):
DELIMITER //
CREATE TRIGGER after_order_delete
AFTER DELETE ON orders FOR EACH ROW
BEGINUPDATE goodsSET num = num + OLD.onumWHERE gid = OLD.gid;
END //

测试触发器:
删除订单:
DELETE FROM orders WHERE oid = 1;


订单删除前商品数量 订单删除后商品数量
创建触发器并测试(修改订单时,更新商品数量):
DELIMITER //
CREATE TRIGGER after_order_update
AFTER UPDATE ON orders
FOR EACH ROW
BEGINUPDATE goodsSET num = num + OLD.onum - NEW.onumWHERE gid = OLD.gid;
END //

测试触发器:
向订单插入数据:
INSERT INTO orders(gid, name, price, onum, otime) VALUES('A0001', '橡皮', 2.5, 10, '2025-11-11');
将订单值由10修改为20:
UPDATE orders SET onum = 20 WHERE oid = 1;


插入订单后商品数量 修改订单商品数值后商品数量
存储过程
存储过程前提准备:
创建并使用数据库:
CREATE DATABASE IF NOT EXISTS mydb7_openlab;
USE mydb7_openlab;

创建emp_new表:
CREATE TABLE IF NOT EXISTS emp_new (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(20) NOT NULL,age INT,salary DECIMAL(10,2),deptno INT);

存储过程创建并测试:
创建存储过程s1并测试(提取表中所有员工姓名与工资):
创建s1:
DELIMITER //
CREATE PROCEDURE s1()
BEGINSELECT name, salary FROM emp_new;
END //
(使用“DELIMITER ;”将结束符号改回分号)

测试s1:
插入数据:
INSERT INTO emp_new(name, age, salary, deptno) VALUES('张三', 25, 5000, 10),('李四', 30, 6000, 10),('王五', 35, 7000, 20);
CALL s1:

创建s2并测试(输入员工姓名返回员工年龄):
创建s2:
DELIMITER //
CREATE PROCEDURE s2(IN emp_name VARCHAR(20), OUT emp_age INT)
BEGINSELECT age INTO emp_age FROM emp_new WHERE name = emp_name;
END //

测试s2:
SET @age = 0;
CALL s2('张三', @age);
SELECT @age;

创建s3并测试(输入部门号返回部门平均工资):
创建s3:
DELIMITER //
CREATE PROCEDURE s3(IN dept_no INT, OUT avg_salary DECIMAL(10,2))
BEGINSELECT AVG(salary) INTO avg_salary FROM emp_new WHERE deptno = dept_no;
END //

测试s3:
SET @avg_sal = 0;
CALL s3(10, @avg_sal);
SELECT @avg_sal;

