在实际操作中,不是单条SQL语句所能实现。因为实现这个完整操作需要编写针对表的多条SQL语句。在执行过程中需要根据前面SQL语句的执行结果有选择的执行后面的SQL语句。因此,需要用到MySQL软件提供的数据库对象存储过程和函数。
存储过程和函数可以简单理解为一条或多条SQL语句的集合。存储过程和函数就是事先经过编译并存储在数据库中的一段SQL语句集合。
存储过程和函数的执行不是由程序调用,也不是由手动启动,而是由事件来触发、激活从而实现执行。而存储过程和函数的执行,则需要手动调用存储过程和函数的名字并需要指定相应的参数。
函数必须有返回值,而存储过程没有。存储过程的参数类型远远多于函数参数类型。
存储过程和函数的优点:
存储过程和函数允许标准组件式编程,提高了SQL语句的重用性、共享性和可移植性;
存储过程和函数能够实现较快的执行速度,能够减少网络流量;
存储过程和函数可以被作为一种安全机制来利用。
1.存储过程和函数创建
#创建名为proce_employee_sal的存储过程
DELIMITER $$
CREATE PROCEDURE proce_employee_sal ()
COMMENT '查询所有雇员的工资'
BEGIN
SELECT sal
FROM t_employee;
END$$
DELIMITER;
上述代码,创建了一个名为proce_employee_sal的存储过程,主要用来实现通过SELECT语句从t_employee表中查询sal字段值,实现查询雇员工资功能。
#创建名为func_employee_sal的函数
DELIMITER $$
CREATE FUNCTION func_employee_sal (empno INT (11))
RETURNS DOUBLE(10,2)
COMMENT '查询某个雇员的工资'
BEGIN
RETURN (SELECT sal
FROM t_employee
WHERE t_employee.empno=empno);
END$$
DELIMITER ;
在上述代码,创建了一个名为func_employee_sal的函数,该函数拥有一个类型为INT(11)名为empno的参数,返回值为DOUBLE(10,2)类型。SELECT语句从t_employee表中查询empno字段值等于所传入参数empno值的记录,同时并将该条记录的sal字段的值返回。
2.使用游标
MySQL软件的查询语句可以返回多条记录结果,通过游标来遍历这些记录结果。通过指定由SELECT语句返回的行集合(包括满足该语句的WHERE子句所列条件的所有行),由该语句返回完整的行集合叫作结果集。应用程序需要一种机制来一次处理结果集中的一行或连续的几行,而游标通过每次指向一条记录完成与应用程序的交互。
游标可以看做是一种数据类型,可以用来遍历结果集,相当于指针,或者是数组中的下标。处理结果集的方法可以通过游标定位到结果集的某一行,从当前结果集的位置搜索一行或一部分行或者对结果集中的当前行进行数据修改。
DROP PROCEDURE IF EXISTS employee_count;
DELIMITER $
#创建存储过程
CREATE PROCEDURE employee_count (OUT NUM INTEGER)
BEGIN
#声明变量
DECLARE employee_sal INTEGER;
DECLARE flag INTEGER;
#声明游标
DECLARE cursor_employee
CURSOR FOR SELECT sal FROM t_employee;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET flag=1;
#设置结束标志
SET flag=0;
SET NUM=0;
#打开游标
OPEN cursor_employee;
#遍历游标指向的结果集
FETCH cursor_employee INTO employee_sal;
WHILE flag<>1 DO
IF employee_sal >999 THEN
SET num=num+1;
END IF;
FETCH cursor_employee INTO employee_sal;
END WHILE;
#关闭游标
CLOSE cursor_employee;
END
$
DELIMITER ;
3.查看存储过程和函数
SHOW PROCEDURE STATUS LIKE 'proce_employee_sal' \G
SHOW FUNCTION STATUS LIKE 'func_employee_sal' \G
通过查看系统表information_schema.routines实现查看存储过程和函数的信息
USE information_schema;
SELECT * FROM routines \G;
SELECT *
FROM ROUTINES
WHERE SPECIFIC_NAME='proce_employee_sal' \G
SHOW CREATE PROCEDURE proce_employee_sal \G #查看存储过程定义信息
SHOW CREATE FUNCTION func_name \G #查看函数定义信息
4.修改存储过程和函数
ALTER TABLE t_dept
RENAME tab_dept;
5.删除存储过程和函数
DROP PROCEDURE proce_name;
最后通过系统表routines查询是否存在存储过程对象proce_name。
SELECT *
FROM ROUTINES
WHERE SPECIFIC_NAME='proce_name' \G