MySQL初级篇——存储过程存储函数的相关概念及应用举例

Posted 张起灵-小哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL初级篇——存储过程存储函数的相关概念及应用举例相关的知识,希望对你有一定的参考价值。

文章目录:

1.什么是存储过程?

2.存储过程操作相关SQL

3.存储过程实操SQL

4.存储函数操作相关SQL

5.存储函数实操SQL

6.存储过程、存储函数的优缺点


1.什么是存储过程?

含义 :存储过程的英文是 Stored Procedure 。它的思想很简单,就是一组经过 预先编译 SQL 语句的封装。 执行过程:存储过程预先存储在 mysql 服务器上,需要执行的时候,客户端只需要向服务器端发出调用 存储过程的命令,服务器端就可以把预先存储好的这一系列 SQL 语句全部执行。 好处 1 、简化操作,提高了 sql 语句的重用性,减少了开发程序员的压力 2 、减少操作过程中的失误,提高效率 3 、减少网络传输量(客户端不需要把所有的 SQL 语句通过网络发给服务器) 4 、减少了 SQL 语句暴露在 网上的风险,也提高了数据查询的安全性 和视图、函数的对比 它和视图有着同样的优点,清晰、安全,还可以减少网络传输量。 不过它和视图不同,视图是 虚拟表 通常不对底层数据表直接操作,而存储过程是程序化的 SQL ,可以 直接操作底层数据表 ,相比于面向集 合的操作方式,能够实现一些更复杂的数据处理。 一旦存储过程被创建出来,使用它就像使用函数一样简单,我们直接通过调用存储过程名即可。 相较于 函数,存储过程是 没有返回值 的。 分类 存储过程的参数类型可以是 IN OUT INOUT 。根据这点分类如下: 1 、没有参数(无参数无返回) 2 、仅仅带 IN 类型(有参数无返回) 3 、仅仅带 OUT 类型(无参数有返 回) 4 、既带 IN 又带 OUT (有参数有返回) 5 、带 INOUT (有参数有返回) 注意: IN OUT INOUT 都可以在一个存储过程中带多个。

2.存储过程操作相关SQL

创建存储过程

DELIMITER $ 
CREATE PROCEDURE 存储过程名(IN|OUT|INOUT 参数名 参数类型,...) [characteristics ...] 
BEGIN
    sql语句1; 
    sql语句2; 
END $
DELIMITER ;
说明: 1 、参数前面的符号的意思 IN :当前参数为输入参数,也就是表示入参; 存储过程只是读取这个参数的值。如果没有定义参数种类, 默认就是 IN ,表示输入参数。 OUT :当前参数为输出参数,也就是表示出参; 执行完成之后,调用这个存储过程的客户端或者应用程序就可以读取这个参数返回的值了。 INOUT :当前参数既可以为输入参数,也可以为输出参数。 2 、形参类型可以是 MySQL 数据库中的任意类型。 3 characteristics 表示创建存储过程时指定的对存储过程的约束条件。 4 、存储过程体中可以有多条 SQL 语句,如果仅仅一条 SQL 语句,则可以省略 BEGIN END。编写存储过程并不是一件简单的事情,可能存储过程中需要复杂的 SQL 语句。 5、需要设置新的结束标记。 因为 MySQL 默认的语句结束符号为分号 ‘;’ 。为了避免与存储过程中 SQL 语句结束符相冲突,需要使用 DELIMITER 改变存储过程的结束符。 比如: “DELIMITER //” 语句的作用是将 MySQL 的结束符设置为 // ,并以 “END //” 结束存储过程。存储过程定 义完毕之后再使用 “DELIMITER ;” 恢复默认结束符。 DELIMITER 也可以指定其他符号作为结束符。 当使用 DELIMITER 命令时,应该避免使用反斜杠( ‘\\’ )字符,因为反斜线是 MySQL 的转义字符。

调用存储过程:

存储过程有多种调用方法。存储过程必须使用 CALL 语句调用,并且存储过程和数据库相关,如果要执行 其他数据库中的存储过程,需要指定数据库名称,例如 CALL dbname.procname
CALL 存储过程名(实参列表)

使用SHOW CREATE语句查看存储过程和函数的创建信息

SHOW CREATE PROCEDURE | FUNCTION 存储过程名或函数名
使用 SHOW STATUS 语句查看存储过程和函数的状态信息
SHOW PROCEDURE | FUNCTION STATUS [LIKE 'pattern']
information_schema.Routines 表中查看存储过程和函数的信息 MySQL 中存储过程和函数的信息存储在 information_schema 数据库下的 Routines 表中。可以通过查询该表 的记录来查询存储过程和函数的信息。其基本语法形式如下:
SELECT * 
FROM information_schema.Routines 
WHERE ROUTINE_NAME='存储过程或函数的名' [AND ROUTINE_TYPE = 'PROCEDURE|FUNCTION'];
删除存储过程和函数,可以使用 DROP 语句,其语法结构如下:
DROP PROCEDURE | FUNCTION [IF EXISTS] 存储过程或函数的名

3.存储过程实操SQL

首先,我们创建两张表。(至于使用哪个数据库,这个我在这里就不指出了,大家随意)

CREATE TABLE admin ( 
		id INT PRIMARY KEY AUTO_INCREMENT, 
		user_name VARCHAR(15) NOT NULL, 
		pwd VARCHAR(25) NOT NULL 
);

CREATE TABLE beauty ( 
		id INT PRIMARY KEY AUTO_INCREMENT, 
		`name` VARCHAR(15) NOT NULL, 
		phone VARCHAR(15) UNIQUE, 
		birth DATE 
);

INSERT INTO beauty(NAME,phone,birth) 
VALUES ('朱茵','13201233453','1982-02-12'), 
('孙燕姿','13501233653','1980-12-09'), 
('田馥甄','13651238755','1983-08-21'), 
('邓紫棋','17843283452','1991-11-12'), 
('刘若英','18635575464','1989-05-18'), 
('杨超越','13761238755','1994-05-11');
创建存储过程 insert_user(), 实现传入用户名和密码,插入到 admin 表中
DELIMITER $
CREATE PROCEDURE insert_user(IN user_name VARCHAR(20), IN pwd VARCHAR(20))
BEGIN
		INSERT INTO admin(user_name,pwd)
		VALUES(user_name,pwd);
END $
DELIMITER ;
SET @user_name := 'zhangsan';
SET @pwd := '123456';
CALL insert_user(@user_name,@pwd);

SELECT * FROM admin;

由于我之前已经测试了一次,所以这里有两条数据。

创建存储过程 get_phone(), 实现传入女神编号,返回女神姓名和女神电话
DELIMITER //
CREATE PROCEDURE get_phone(IN id INT, OUT `name` VARCHAR(20), OUT phone VARCHAR(20))
BEGIN
		SELECT b.`name`, b.phone INTO `name`,phone
		FROM beauty b
		WHERE b.id = id;
END //
DELIMITER ;
CALL get_phone(1, @`name`, @phone);

SELECT @`name`, @phone;

创建存储过程 date_diff() ,实现传入两个女神生日,返回日期间隔大小
DELIMITER $
CREATE PROCEDURE date_diff(IN birth1 DATETIME, IN birth2 DATETIME, OUT result INT)
BEGIN
		SELECT DATEDIFF(birth1,birth2) INTO result;
END $
DELIMITER ;
SET @birth1 = '1992-09-03';
SET @birth2 = '1993-09-02';
CALL date_diff(@birth1, @birth2, @result);

SELECT @result;

创建存储过程 format_date(), 实现传入一个日期,格式化成 xx xx xx 日并返回
DELIMITER //
CREATE PROCEDURE format_date(IN mydate DATETIME, OUT strdate VARCHAR(50))
BEGIN
		SELECT DATE_FORMAT(mydate,'%Y年%m月%d日') INTO strdate;
END //
DELIMITER ;
SET @mydate := '2020-10-24';
CALL format_date(@mydate, @strdate);

SELECT @strdate;

创建存储过程 beauty_limit() ,根据传入的起始索引和条目数,查询女神表的记录
DELIMITER $
CREATE PROCEDURE beauty_limit(IN startIndex INT, IN size INT)
BEGIN
		SELECT *
		FROM beauty
		LIMIT startIndex, size;
END $
DELIMITER ;
CALL beauty_limit(1, 3);

传入 a b 两个值,最终 a b 都翻倍并返回
DELIMITER //
CREATE PROCEDURE add_double(INOUT a INT, INOUT b INT)
BEGIN
		SET a = a * 2;
		SET b = b * 2;
END //
DELIMITER ;
SET @a = 3, @b = 5;
CALL add_double(@a, @b);

SELECT @a, @b;

删除题目5的存储过程  

DROP PROCEDURE IF EXISTS beauty_limit;

SHOW CREATE PROCEDURE beauty_limit;

查看题目6中存储过程的信息  

SHOW CREATE PROCEDURE add_double;


4.存储函数操作相关SQL

创建存储函数

CREATE FUNCTION 函数名(参数名 参数类型,...) RETURNS 返回值类型 [characteristics ...] 
BEGIN
    函数体 #函数体中肯定有 RETURN 语句 
END
说明: 1 、参数列表:指定参数为 IN OUT INOUT 只对 PROCEDURE 是合法的, FUNCTION 中总是默认为 IN 参数。 2 RETURNS type 语句表示函数返回数据的类型;RETURNS 子句只能对 FUNCTION 做指定,对函数而言这是 强制 的。它用来指定函数的返回类型,而且函 数体必须包含一个 RETURN value 语句。 3 characteristic 创建函数时指定的对函数的约束。取值与创建存储过程时相同,这里不再赘述。 4 、函数体也可以用 BEGIN…END 来表示 SQL 代码的开始和结束。如果函数体只有一条语句,也可以省略BEGIN…END

调用存储函数

SELECT 函数名(实参列表)
注意: 若在创建存储函数中报错 you might want to use the less safe log_bin_trust_function_creators variable ,有两种处理方法: 方式 1 :加上必要的函数特性 “[NOT] DETERMINISTIC” “CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA” 方式 2
SET GLOBAL log_bin_trust_function_creators = 1;

对比存储过程和存储函数

关于查看存储函数的属性信息、删除等相关操作,在上面存储过程那里已经给出代码了。


5.存储函数实操SQL

首先,我们需要创建一个新的数据库,然后在这个库下创建两张表:employees、departments,下面给出这两张表的sql脚本代码。

CREATE DATABASE IF NOT EXISTS test15_pro_func;

USE test15_pro_func; 
/*Table structure for table `departments` */

DROP TABLE IF EXISTS `departments`;

CREATE TABLE `departments` (
  `department_id` int(4) NOT NULL DEFAULT '0',
  `department_name` varchar(30) NOT NULL,
  `manager_id` int(6) DEFAULT NULL,
  `location_id` int(4) DEFAULT NULL,
  PRIMARY KEY (`department_id`),
  UNIQUE KEY `dept_id_pk` (`department_id`),
  KEY `dept_loc_fk` (`location_id`),
  KEY `dept_mgr_fk` (`manager_id`),
  CONSTRAINT `dept_loc_fk` FOREIGN KEY (`location_id`) REFERENCES `locations` (`location_id`),
  CONSTRAINT `dept_mgr_fk` FOREIGN KEY (`manager_id`) REFERENCES `employees` (`employee_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `departments` */

insert  into `departments`(`department_id`,`department_name`,`manager_id`,`location_id`) values (10,'Administration',200,1700),(20,'Marketing',201,1800),(30,'Purchasing',114,1700),(40,'Human Resources',203,2400),(50,'Shipping',121,1500),(60,'IT',103,1400),(70,'Public Relations',204,2700),(80,'Sales',145,2500),(90,'Executive',100,1700),(100,'Finance',108,1700),(110,'Accounting',205,1700),(120,'Treasury',NULL,1700),(130,'Corporate Tax',NULL,1700),(140,'Control And Credit',NULL,1700),(150,'Shareholder Services',NULL,1700),(160,'Benefits',NULL,1700),(170,'Manufacturing',NULL,1700),(180,'Construction',NULL,1700),(190,'Contracting',NULL,1700),(200,'Operations',NULL,1700),(210,'IT Support',NULL,1700),(220,'NOC',NULL,1700),(230,'IT Helpdesk',NULL,1700),(240,'Government Sales',NULL,1700),(250,'Retail Sales',NULL,1700),(260,'Recruiting',NULL,1700),(270,'Payroll',NULL,1700);
/*Table structure for table `employees` */

DROP TABLE IF EXISTS `employees`;

CREATE TABLE `employees` (
  `employee_id` int(6) NOT NULL DEFAULT '0',
  `first_name` varchar(20) DEFAULT NULL,
  `last_name` varchar(25) NOT NULL,
  `email` varchar(25) NOT NULL,
  `phone_number` varchar(20) DEFAULT NULL,
  `hire_date` date NOT NULL,
  `job_id` varchar(10) NOT NULL,
  `salary` double(8,2) DEFAULT NULL,
  `commission_pct` double(2,2) DEFAULT NULL,
  `manager_id` int(6) DEFAULT NULL,
  `department_id` int(4) DEFAULT NULL,
  PRIMARY KEY (`employee_id`),
  UNIQUE KEY `emp_email_uk` (`email`),
  UNIQUE KEY `emp_emp_id_pk` (`employee_id`),
  KEY `emp_dept_fk` (`department_id`),
  KEY `emp_job_fk` (`job_id`),
  KEY `emp_manager_fk` (`manager_id`),
  CONSTRAINT `emp_dept_fk` FOREIGN KEY (`department_id`) REFERENCES `departments` (`department_id`),
  CONSTRAINT `emp_job_fk` FOREIGN KEY (`job_id`) REFERENCES `jobs` (`job_id`),
  CONSTRAINT `emp_manager_fk` FOREIGN KEY (`manager_id`) REFERENCES `employees` (`employee_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `employees` */

insert  into `employees`(`employee_id`,`first_name`,`last_name`,`email`,`phone_number`,`hire_date`,`job_id`,`salary`,`commission_pct`,`manager_id`,`department_id`) values (100,'Steven','King','SKING','515.123.4567','1987-06-17','AD_PRES',24000.00,NULL,NULL,90),(101,'Neena','Kochhar','NKOCHHAR','515.123.4568','1989-09-21','AD_VP',17000.00,NULL,100,90),(102,'Lex','De Haan','LDEHAAN','515.123.4569','1993-01-13','AD_VP',17000.00,NULL,100,90),(103,'Alexander','Hunold','AHUNOLD','590.423.4567','1990-01-03','IT_PROG',9000.00,NULL,102,60),(104,'Bruce','Ernst','BERNST','590.423.4568','1991-05-21','IT_PROG',6000.00,NULL,103,60),(105,'David','Austin','DAUSTIN','590.423.4569','1997-06-25','IT_PROG',4800.00,NULL,103,60),(106,'Valli','Pataballa','VPATABAL','590.423.4560','1998-02-05','IT_PROG',4800.00,NULL,103,60),(107,'Diana','Lorentz','DLORENTZ','590.423.5567','1999-02-07','IT_PROG',4200.00,NULL,103,60),(108,'Nancy','Greenberg','NGREENBE','515.124.4569','1994-08-17','FI_MGR',12000.00,NULL,101,100),(109,'Daniel','Faviet','DFAVIET','515.124.4169','1994-08-16','FI_ACCOUNT',9000.00,NULL,108,100),(110,'John','Chen','JCHEN','515.124.4269','1997-09-28','FI_ACCOUNT',8200.00,NULL,108,100),(111,'Ismael','Sciarra','ISCIARRA','515.124.4369','1997-09-30','FI_ACCOUNT',7700.00,NULL,108,100),(112,'Jose Manuel','Urman','JMURMAN','515.124.4469','1998-03-07','FI_ACCOUNT',7800.00,NULL,108,100),(113,'Luis','Popp','LPOPP','515.124.4567','1999-12-07','FI_ACCOUNT',6900.00,NULL,108,100),(114,'Den','Raphaely','DRAPHEAL','515.127.4561','1994-12-07','PU_MAN',11000.00,NULL,100,30),(115,'Alexander','Khoo','AKHOO','515.127.4562','1995-05-18','PU_CLERK',3100.00,NULL,114,30),(116,'Shelli','Baida','SBAIDA','515.127.4563','1997-12-24','PU_CLERK',2900.00,NULL,114,30),(117,'Sigal','Tobias','STOBIAS','515.127.4564','1997-07-24','PU_CLERK',2800.00,NULL,114,30),(118,'Guy','Himuro','GHIMURO','515.127.4565','1998-11-15','PU_CLERK',2600.00,NULL,114,30),(119,'Karen','Colmenares','KCOLMENA','515.127.4566','1999-08-10','PU_CLERK',2500.00,NULL,114,30),(120,'Matthew','Weiss','MWEISS','650.123.1234','1996-07-18','ST_MAN',8000.00,NULL,100,50),(121,'Adam','Fripp','AFRIPP','650.123.2234','1997-04-10','ST_MAN',8200.00,NULL,100,50),(122,'Payam','Kaufling','PKAUFLIN','650.123.3234','1995-05-01','ST_MAN',7900.00,NULL,100,50),(123,'Shanta','Vollman','SVOLLMAN','650.123.4234','1997-10-10','ST_MAN',6500.00,NULL,100,50),(124,'Kevin','Mourgos','KMOURGOS','650.123.5234','1999-11-16','ST_MAN',5800.00,NULL,100,50),(125,'Julia','Nayer','JNAYER','650.124.1214','1997-07-16','ST_CLERK',3200.00,NULL,120,50),(126,'Irene','Mikkilineni','IMIKKILI','650.124.1224','1998-09-28','ST_CLERK',2700.00,NULL,120,50),(127,'James','Landry','JLANDRY','650.124.1334','1999-01-14','ST_CLERK',2400.00,NULL,120,50),(128,'Steven','Markle','SMARKLE','650.124.1434','2000-03-08','ST_CLERK',2200.00,NULL,120,50),(129,'Laura','Bissot','LBISSOT','650.124.5234','1997-08-20','ST_CLERK',3300.00,NULL,121,50),(130,'Mozhe','Atkinson','MATKINSO','650.124.6234','1997-10-30','ST_CLERK',2800.00,NULL,121,50),(131,'James','Marlow','JAMRLOW','650.124.7234','1997-02-16','ST_CLERK',2500.00,NULL,121,50),(132,'TJ','Olson','TJOLSON','650.124.8234','1999-04-10','ST_CLERK',2100.00,NULL,121,50),(133,'Jason','Mallin','JMALLIN','650.127.1934','1996-06-14','ST_CLERK',3300.00,NULL,122,50),(134,'Michael','Rogers','MROGERS','650.127.1834','1998-08-26','ST_CLERK',2900.00,NULL,122,50),(135,'Ki','Gee','KGEE','650.127.1734','1999-12-12','ST_CLERK',2400.00,NULL,122,50),(136,'Hazel','Philtanker','HPHILTAN','650.127.1634','2000-02-06','ST_CLERK',2200.00,NULL,122,50),(137,'Renske','Ladwig','RLADWIG','650.121.1234','1995-07-14','ST_CLERK',3600.00,NULL,123,50),(138,'Stephen','Stiles','SSTILES','650.121.2034','1997-10-26','ST_CLERK',3200.00,NULL,123,50),(139,'John','Seo','JSEO','650.121.2019','1998-02-12','ST_CLERK',2700.00,NULL,123,50),(140,'Joshua','Patel','JPATEL','650.121.1834','1998-04-06','ST_CLERK',2500.00,NULL,123,50),(141,'Trenna','Rajs','TRAJS','650.121.8009','1995-10-17','ST_CLERK',3500.00,NULL,124,50),(142,'Curtis','Davies','CDAVIES','650.121.2994','1997-01-29','ST_CLERK',3100.00,NULL,124,50),(143,'Randall','Matos','RMATOS','650.121.2874','1998-03-15','ST_CLERK',2600.00,NULL,124,50),(144,'Peter','Vargas','PVARGAS','650.121.2004','1998-07-09','ST_CLERK',2500.00,NULL,124,50),(145,'John','Russell','JRUSSEL','011.44.1344.429268','1996-10-01','SA_MAN',14000.00,0.40,100,80),(146,'Karen','Partners','KPARTNER','011.44.1344.467268','1997-01-05','SA_MAN',13500.00,0.30,100,80),(147,'Alberto','Errazuriz','AERRAZUR','011.44.1344.429278','1997-03-10','SA_MAN',12000.00,0.30,100,80),(148,'Gerald','Cambrault','GCAMBRAU','011.44.1344.619268','1999-10-15','SA_MAN',11000.00,0.30,100,80),(149,'Eleni','Zlotkey','EZLOTKEY','011.44.1344.429018','2000-01-29','SA_MAN',10500.00,0.20,100,80),(150,'Peter','Tucker','PTUCKER','011.44.1344.129268','1997-01-30','SA_REP',10000.00,0.30,145,80),(151,'David','Bernstein','DBERNSTE','011.44.1344.345268','1997-03-24','SA_REP',9500.00,0.25,145,80),(152,'Peter','Hall','PHALL','011.44.1344.478968','1997-08-20','SA_REP',9000.00,0.25,145,80),(153,'Christopher','Olsen','COLSEN','011.44.1344.498718','1998-03-30','SA_REP',8000.00,0.20,145,80),(154,'Nanette','Cambrault','NCAMBRAU','011.44.1344.987668','1998-12-09','SA_REP',7500.00,0.20,145,80),(155,'Oliver','Tuvault','OTUVAULT','011.44.1344.486508','1999-11-23','SA_REP',7000.00,0.15,145,80),(156,'Janette','King','JKING','011.44.1345.429268','1996-01-30','SA_REP',10000.00,0.35,146,80),(157,'Patrick','Sully','PSULLY','011.44.1345.929268','1996-03-04','SA_REP',9500.00,0.35,146,80),(158,'Allan','McEwen','AMCEWEN','011.44.1345.829268','1996-08-01','SA_REP',9000.00,0.35,146,80),(159,'Lindsey','Smith','LSMITH','011.44.1345.729268','1997-03-10','SA_REP',8000.00,0.30,146,80),(160,'Louise','Doran','LDORAN','011.44.1345.629268','1997-12-15','SA_REP',7500.00,0.30,146,80),(161,'Sarath','Sewall','SSEWALL','011.44.1345.529268','1998-11-03','SA_REP',7000.00,0.25,146,80),(162,'Clara','Vishney','CVISHNEY','011.44.1346.129268','1997-11-11','SA_REP',10500.00,0.25,147,80),(163,'Danielle','Greene','DGREENE','011.44.1346.229268','1999-03-19','SA_REP',9500.00,0.15,147,80),(164,'Mattea','Marvins','MMARVINS','011.44.1346.329268','2000-01-24','SA_REP',7200.00,0.10,147,80),(165,'David','Lee','DLEE','011.44.1346.529268','2000-02-23','SA_REP',6800.00,0.10,147,80),(166,'Sundar','Ande','SANDE','011.44.1346.629268','2000-03-24','SA_REP',6400.00,0.10,147,80),(167,'Amit','Banda','ABANDA','011.44.1346.729268','2000-04-21','SA_REP',6200.00,0.10,147,80),(168,'Lisa','Ozer','LOZER','011.44.1343.929268','1997-03-11','SA_REP',11500.00,0.25,148,80),(169,'Harrison','Bloom','HBLOOM','011.44.1343.829268','1998-03-23','SA_REP',10000.00,0.20,148,80),(170,'Tayler','Fox','TFOX','011.44.1343.729268','1998-01-24','SA_REP',9600.00,0.20,148,80),(171,'William','Smith','WSMITH','011.44.1343.629268','1999-02-23','SA_REP',7400.00,0.15,148,80),(172,'Elizabeth','Bates','EBATES','011.44.1343.529268','1999-03-24','SA_REP',7300.00,0.15,148,80),(173,'Sundita','Kumar','SKUMAR','011.44.1343.329268','2000-04-21','SA_REP',6100.00,0.10,148,80),(174,'Ellen','Abel','EABEL','011.44.1644.429267','1996-05-11','SA_REP',11000.00,0.30,149,80),(175,'Alyssa','Hutton','AHUTTON','011.44.1644.429266','1997-03-19','SA_REP',8800.00,0.25,149,80),(176,'Jonathon','Taylor','JTAYLOR','011.44.1644.429265','1998-03-24','SA_REP',8600.00,0.20,149,80),(177,'Jack','Livingston','JLIVINGS','011.44.1644.429264','1998-04-23','SA_REP',8400.00,0.20,149,80),(178,'Kimberely','Grant','KGRANT','011.44.1644.429263','1999-05-24','SA_REP',7000.00,0.15,149,NULL),(179,'Charles','Johnson','CJOHNSON','011.44.1644.429262','2000-01-04','SA_REP',6200.00,0.10,149,80),(180,'Winston','Taylor','WTAYLOR','650.507.9876','1998-01-24','SH_CLERK',3200.00,NULL,120,50),(181,'Jean','Fleaur','JFLEAUR','650.507.9877','1998-02-23','SH_CLERK',3100.00,NULL,120,50),(182,'Martha','Sullivan','MSULLIVA','650.507.9878','1999-06-21','SH_CLERK',2500.00,NULL,120,50),(183,'Girard','Geoni','GGEONI','650.507.9879','2000-02-03','SH_CLERK',2800.00,NULL,120,50),(184,'Nandita','Sarchand','NSARCHAN','650.509.1876','1996-01-27','SH_CLERK',4200.00,NULL,121,50),(185,'Alexis','Bull','ABULL','650.509.2876','1997-02-20','SH_CLERK',4100.00,NULL,121,50),(186,'Julia','Dellinger','JDELLING','650.509.3876','1998-06-24','SH_CLERK',3400.00,NULL,121,50),(187,'Anthony','Cabrio','ACABRIO','650.509.4876','1999-02-07','SH_CLERK',3000.00,NULL,121,50),(188,'Kelly','Chung','KCHUNG','650.505.1876','1997-06-14','SH_CLERK',3800.00,NULL,122,50),(189,'Jennifer','Dilly','JDILLY','650.505.2876','1997-08-13','SH_CLERK',3600.00,NULL,122,50),(190,'Timothy','Gates','TGATES','650.505.3876','1998-07-11','SH_CLERK',2900.00,NULL,122,50),(191,'Randall','Perkins','RPERKINS','650.505.4876','1999-12-19','SH_CLERK',2500.00,NULL,122,50),(192,'Sarah','Bell','SBELL','650.501.1876','1996-02-04','SH_CLERK',4000.00,NULL,123,50),(193,'Britney','Everett','BEVERETT','650.501.2876','1997-03-03','SH_CLERK',3900.00,NULL,123,50),(194,'Samuel','McCain','SMCCAIN','650.501.3876','1998-07-01','SH_CLERK',3200.00,NULL,123,50),(195,'Vance','Jones','VJONES','650.501.4876','1999-03-17','SH_CLERK',2800.00,NULL,123,50),(196,'Alana','Walsh','AWALSH','650.507.9811','1998-04-24','SH_CLERK',3100.00,NULL,124,50),(197,'Kevin','Feeney','KFEENEY','650.507.9822','1998-05-23','SH_CLERK',3000.00,NULL,124,50),(198,'Donald','OConnell','DOCONNEL','650.507.9833','1999-06-21','SH_CLERK',2600.00,NULL,124,50),(199,'Douglas','Grant','DGRANT','650.507.9844','2000-01-13','SH_CLERK',2600.00,NULL,124,50),(200,'Jennifer','Whalen','JWHALEN','515.123.4444','1987-09-17','AD_ASST',4400.00,NULL,101,10),(201,'Michael','Hartstein','MHARTSTE','515.123.5555','1996-02-17','MK_MAN',13000.00,NULL,100,20),(202,'Pat','Fay','PFAY','603.123.6666','1997-08-17','MK_REP',6000.00,NULL,201,20),(203,'Susan','Mavris','SMAVRIS','515.123.7777','1994-06-07','HR_REP',6500.00,NULL,101,40),(204,'Hermann','Baer','HBAER','515.123.8888','1994-06-07','PR_REP',10000.00,NULL,101,70),(205,'Shelley','Higgins','SHIGGINS','515.123.8080','1994-06-07','AC_MGR',12000.00,NULL,101,110),(206,'William','Gietz','WGIETZ','515.123.8181','1994-06-07','AC_ACCOUNT',8300.00,NULL,205,110);
然后,我们以上面两张表为基表,创建两张新的表,用于实操存储函数。(避免影响以上两张表中的数据)
CREATE TABLE employees 
AS
SELECT * FROM atguigudb.`employees`; 

CREATE TABLE departments 
AS
SELECT * FROM atguigudb.`departments`;
创建函数 get_count(), 返回公司的员工个数
DELIMITER $
CREATE FUNCTION get_count() RETURNS INT
BEGIN
		RETURN (SELECT COUNT(*) FROM employees);
END $
DELIMITER ;
SELECT get_count();

创建函数 ename_salary(), 根据员工姓名,返回它的工资
DELIMITER //
CREATE FUNCTION ename_salary(emp_name VARCHAR(20)) RETURNS DOUBLE
BEGIN
		RETURN (
				SELECT salary
				FROM employees
				WHERE last_name = emp_name
		);
END //
DELIMITER ;
SELECT ename_salary('Abel');

创建函数 dept_sal() , 根据部门名,返回该部门的平均工资
DELIMITER $
CREATE FUNCTION dept_sal(dept_name VARCHAR(20)) RETURNS DOUBLE
BEGIN
		RETURN (
				SELECT AVG(salary)
				FROM employees e
				JOIN departments d
				ON e.department_id = d.department_id
				WHERE d.department_name = dept_name
		);
END $
DELIMITER ;
SET @dept_name := 'Marketing';
SELECT dept_sal(@dept_name);

创建函数 add_float() ,实现传入两个 float ,返回二者之和
DELIMITER //
CREATE FUNCTION add_float(num1 DECIMAL(3,2), num2 DECIMAL(3,2)) RETURNS DECIMAL(3,2)
BEGIN
		RETURN (
				SELECT num1 + num2
		);
END //
DELIMITER ;
SET @num1 := 1.11;
SET @num2 := 2.22;
SELECT add_float(@num1, @num2);

删除add_float这个存储函数。

DROP FUNCTION IF EXISTS add_float;

SHOW CREATE FUNCTION add_float;

查看dept_sal存储函数的属性信息。

SHOW CREATE FUNCTION dept_sal;


6.存储过程、存储函数的优缺点

尽管存储过程有诸多优点,但是对于存储过程的使用, 一直都存在着很多争议 ,比如有些公司对于大型项目要求使用存储过程,而有些公司在手册中明确禁止使用存储过程,为什么这些公司对存储过程的使 用需求差别这么大呢? 优点: 1 、存储过程可以一次编译多次使用。 存储过程只在创建时进行编译,之后的使用都不需要重新编译,这就提升了 SQL 的执行效率。 2 、可以减少开发工作量。 将代码 封装 成模块,实际上是编程的核心思想之一,这样可以把复杂的问题拆解成不同的模块,然后模块之间可以 重复使用 ,在减少开发工作量的同时,还能保证代码的结构清 晰。 3 、存储过程的安全性强。 我们在设定存储过程的时候可以 设置对用户的使用权限 ,这样就和视图一样具有较强的安全性。 4 、可以减少网络传输量。 因为代码封装到存储过程中,每次使用只需要调用存储过程即可,这样就减 少了网络传输量。 5 、良好的封装性。 在进行相对复杂的数据库操作时,原本需要使用一条一条的 SQL 语句,可能要连接多次数据库才能完成的操作,现在变成了一次存储过程,只需要 连接一次即可

缺点:

基于上面这些优点,不少大公司都要求大型项目使用存储过程,比如微软、 IBM 等公司。但是国内的阿 里并不推荐开发人员使用存储过程,这是为什么呢? 阿里开发规范 【强制】禁止使用存储过程,存储过程难以调试和扩展,更没有移植性。 存储过程虽然有诸如上面的好处,但缺点也是很明显的。 1 、可移植性差。 存储过程不能跨数据库移植,比如在 MySQL Oracle SQL Server 里编写的存储过 程,在换成其他数据库时都需要重新编写。 2 、调试困难。 只有少数 DBMS 支持存储过程的调试。对于复杂的存储过程来说,开发和维护都不容 易。虽然也有一些第三方工具可以对存储过程进行调试,但要收费。 3 、存储过程的版本管理很困难。 比如数据表索引发生变化了,可能会导致存储过程失效。我们在开发 软件的时候往往需要进行版本管理,但是存储过程本身没有版本控制,版本迭代更新的时候很麻烦。 4 、它不适合高并发的场景。 高并发的场景需要减少数据库的压力,有时数据库会采用分库分表的方式,而且对可扩展性要求很高,在这种情况下,存储过程会变得难以维护, 增加数据库的压力 ,显然就 不适用了。

以上是关于MySQL初级篇——存储过程存储函数的相关概念及应用举例的主要内容,如果未能解决你的问题,请参考以下文章

MySQL高级篇——索引视图存储过程和函数触发器的相关概念及操作

MySQL初级篇——视图的相关概念及应用举例

MySQL初级篇——视图的相关概念及应用举例

PL/SQL 包的概念及创建使用

数据库的概念及简单Mysql数据操作

mysql 初级篇 触发器存储过程游标