mysql advanced | stored procedures
foreword
I do not produce knowledge, I am just a porter of knowledge, the following content is from Bilibili - MySQL database entry to proficiency :
1. Introduction
1 Overview
A stored procedure is a collection of SQL statements that have been compiled and stored in the database in advance. Calling a stored procedure can simplify a lot of work for application developers, reduce data transmission between the database and the application server, and improve the efficiency of database processing. good.
The idea of a stored procedure is very simple, that is, code encapsulation and reuse at the SQL language level of the database.
Features:
- encapsulation, multiplexing
- Can accept parameters and return data
- The network interaction between the application server and the database can be reduced through the stored procedure, and the efficiency can be improved
A stored function is also a piece of SQL that has been compiled and stored in the database in advance. The difference between a stored procedure and a stored function is that the function must have a return value, while the stored procedure does not.
- Function: is a procedure that returns a value;
- Procedure: is a function that does not return a value;
2. Commonly used sentences
1. Create a stored procedure
创建存储过程:
-- procedure_name 存储过程名称
-- proc_parameter[,...] 参数列表
CREATE PROCEDURE procedure_name ([proc_parameter[,...]])
begin
-- SQL语句
end ;
Example:
-- 创建存储过程 countStudent:查询学生总数
DELIMITER $
CREATE PROCEDURE countStudent()
BEGIN
SELECT COUNT(id) FROM student;
END$
DELIMITER ;
DELIMITE:
This keyword is used to declare the delimiter of the SQL statement, telling the MySQL interpreter whether the command in this segment has ended and whether mysql can be executed. By default, the delimiter is a semicolon ";". In the command line client, if a line of command ends with a semicolon, mysql will execute the command after pressing Enter.
When defining a stored function on the command line, we usually define the delimiter of the SQL statement as '$', or '$$', etc., and then change the delimiter back after the end of END.
2. Call the stored procedure
调用存储过程:
-- procedure_name 存储过程名称
-- proc_parameter[,...] 参数列表
call procedure_name([proc_parameter[,...]]);
For example:
-- 调用查询学生数量的存储过程
call countStudent();
3. View stored procedures
After the stored procedure is successfully executed, it will be generated in MySQL. Generally, the tools connected to MySQL will display the stored procedure in the database. For example, you can
query the information related to the stored procedure through the following sql.
查询db_name数据库中的所有的存储过程:
-- 查询db_name数据库中的所有的存储过程
select name from mysql.proc where db='db_name';
Example:
select name from mysql.proc where db='tby';
查询存储过程的状态信息:
-- 查询存储过程的状态信息
SHOW PROCEDURE STATUS;
查询指定数据库的存储过程及状态信息:
-- 查询指定数据库的存储过程及状态信息
SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'db_name'
Example:
-- 查询指定数据库的存储过程及状态信息
SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'tby'
查询某个存储过程的定义:
-- 查询某个存储过程的定义
-- procedure_name 存储过程名称
show create procedure procedure_name;
Example:
show create procedure countStudent;
You can see the contents of Create Procedure
this field are as follows:
CREATE DEFINER=`root`@`%` PROCEDURE `countStudent`()
begin
select count(id) from student;
end
ps: DEFINER=`root`@`%` This means that the stored procedure is defined by the root user on the host as %, if it is not specified when creating the stored procedure, it will be added by default
4. Delete the stored procedure
删除某个存储过程:
-- 删除某个存储过程
DROP PROCEDURE [IF EXISTS] procedure_name;
Example:
DROP PROCEDURE IF EXISTS countStudent;
After deleting, execute the sql that queries the stored procedure
-- 查询数据库中指定存储过程
select name from mysql.proc where db='tby' and name = 'countStudent';
The result is as follows:
3. Basic Grammar
Stored procedures are programmable, which means that variables, expressions, and control structures can be used to complete more complex functions.
1. Variables
System variables are provided by the MySQL server, not user-defined, but belong to the server level, and are divided into global variables (GLOBAL) and session variables (SESSION).
- View system variables (if no type is specified, the default is SESSION)
查看所有的系统变量:
SHOW [SESSION|GLOBAL] VARIABLES;
可以通过 LIKE 模糊匹配方式查找变量:
SHOW [SESSION|GLOBAL] VARIABLES LIKE '...';
查看指定变量的值:
SELECT @@[SESSION|GLOBAL] 系统变量名;
- set system variables
SET [SESSION|GLOBAL] 系统变量名;
SET @@[SESSION|GLOBAL] 系统变量名;
- DECLARE
With DECLARE
can define a local variable, the scope of the variable can only be BEGIN...END
in the block.
grammar:
DECLARE var_name[,...] type [DEFAULT value]
Example:
delimiter $
create procedure pro_declare()
begin
-- 定义一个变量 num 默认值为 5
declare num int default 5;
-- 返回 num 的值,并且在 num 前拼接字符串 'num的值为:'
select concat('num的值为:',num);
end$
delimiter ;
- SET
Use SET for direct assignment, you can assign constants or expressions, the specific syntax is as follows:
SET var_name = expr [, var_name = expr]
Example:
DELIMITER $
CREATE PROCEDURE pro_set()
BEGIN
-- 定义一个 name 的变量
DECLARE name VARCHAR(20);
-- 对 name 变量进行赋值,为 'mike'
SET name = 'mike';
-- 返回 name
SELECT name;
END$
DELIMITER ;
You can also perform assignment operations through select ... into:
Example:
DELIMITER $
CREATE PROCEDURE pro_set_into()
BEGIN
-- 定义一个为 int 类型的变量 num
DECLARE num int;
-- 将查询到的学生总数赋值给 num
SELECT count(*) into num from student;
-- 返回学生总数
SELECT concat('学生数量共:',num);
END$
DELIMITER ;
2. Condition judgment
Grammatical structures:
if search_condition then statement_list
[elseif search_condition then statement_list] ...
[else statement_list]
end if;
Example:
根据定义的身高变量,判定当前身高的所属的身材类型
180 及以上 ----------> 身材高挑
170 - 180 ---------> 标准身材
170 以下 ---------> 一般身材
DELIMITER $
create procedure pro_if_else()
begin
declare height int default 175;
declare description varchar(50) default '';
if height >= 180 then
set description = '身材高挑';
elseif height >= 170 and height < 180 then
set description = '标准身材';
else
set description = '一般身材';
end if;
select concat('身高',height,'对应得身材类型为:',description) as description;
end$
DELIMITER ;
call pro_if_else();
The result of the call is displayed as follows:
3. Pass parameters
Grammar format:
-- procedure_name 存储过程名称
create procedure procedure_name([in/out/inout] 参数名 参数类型)
...
- IN: This parameter can be used as an input, that is, the caller needs to pass in a value. By default
- OUT: The parameter is used as an output, that is, the parameter can be used as a return value
- INOUT: can be used as both an input parameter and an output parameter
(1) IN-input
Requirement: According to the custom height variable, determine the body type of the current height
DELIMITER $
create procedure pro_in(in height int)
begin
declare description varchar(50) default '';
if height >= 180 then
set description = '身材高挑';
elseif height >= 170 and height < 180 then
set description = '标准身材';
else
set description = '一般身材';
end if;
select concat('身高',height,'对应得身材类型为:',description) as description;
end$
DELIMITER ;
call pro_in(189);
The result of the call is displayed as follows:
(1) OUT- output
Requirement: Get the body type of the current height according to the incoming height variable
DELIMITER $
create procedure pro_in_out(in height int, out description varchar(50))
begin
if height >= 180 then
set description = '身材高挑';
elseif height >= 170 and height < 180 then
set description = '标准身材';
else
set description = '一般身材';
end if;
select concat('身高',height,'对应得身材类型为:',description) as des;
end$
DELIMITER ;
call pro_in_out(169,@description);
The result of the call is displayed as follows:
PS:
@description
: This kind of variable needs to add the "@" symbol in front of the variable name, which is called a user session variable, which means that it has a role in the entire session process, which is similar to a global variable.
@@global.sort_ buffer_size
: This kind of "@@" symbol is added before the variable, which is called system variable
Check:
select @description;
4. case structure
Grammatical structure:
Method 1:
CASE case_value
WHEN when_value THEN statement_list
[WHEN when_value THEN statement_list] ...
[ELSE statement_list]
END CASE;
Method 2:
CASE
WHEN search_condition THEN statement_list
[WHEN search_condition THEN statement_list] ...
[ELSE statement_list]
END CASE ;
Requirements: Given a month, then calculate the quarter it is in
Example:
DELIMITER $
create procedure pro_case(in mon int)
begin
declare result varchar(10);
case
when mon>=1 and mon <=3 then
set result = '第一季度';
when mon>=4 and mon <=6 then
set result = '第二季度';
when mon>=7 and mon <=9 then
set result = '第三季度';
ELSE
set result = '第四季度';
end case;
select concat('传递的月份为:',mon,',计算出的结果为:',result) as content;
end$
DELIMITER ;
call pro_case(4);
The result of the call is displayed as follows:
5. while loop
Grammatical structures:
while search_condition do
statement_list
end while;
Requirement: Calculate the value added from 1 to n
Example:
DELIMITER $
create procedure pro_while(in n int)
begin
declare total int default 0;
declare num int default 1;
while num<=n do
set total = total + num;
set num = num + 1;
end while;
select total;
end$
DELIMITER ;
call pro_while(10);
The result of the call is displayed as follows:
6. Repeat structure
A conditional loop control statement that exits the loop when the condition is met. while is executed when the condition is met, and repeat is exited when the condition is met (similar to the do ... while statement).
Grammatical structures:
REPEAT
statement_list
UNTIL search_condition
END REPEAT;
Requirement: Calculate the value added from 1 to n
DELIMITER $
create procedure pro_repeat(in n int)
begin
declare total int default 0;
repeat
set total = total + n;
set n = n-1;
until n = 0
end repeat;
select total;
end$
DELIMITER ;
call pro_repeat(10);
The result of the call is displayed as follows:
7. loop statement
LOOP implements a simple loop, and the conditions for exiting the loop need to be defined using other statements, which can usually be implemented using LEAVE
the statement . The specific syntax is as follows:
[begin_labe1:] LOOP
statement_list
END LOOP [end_labe1]
If you do not add a statement to exit the loop in the statement_list, then the LOOP statement can be used to achieve the effect of a simple loop.
8. leave statement
Used to exit from a labeled process construct, usually used with BEGIN ... END or loops. Here's LOOP
a LEAVE
simple example using and to exit the loop:
DELIMITER $
create procedure pro_leave_Loop(n int)
begin
declare total int default 0;
c:loop
set total = total + n;
set n = n-1;
if n <= 0 then
leave c;
end if;
end loop c;
select total;
end$
DELIMITER ;
call pro_leave_Loop(10);
The result of the call is displayed as follows:
9. Condition handlers
Condition handler (Handler): It can be used to define the processing steps to respond when a problem is encountered in the flow control structure process. The specific syntax is:
-- handler_action 条件处理程序的类型
-- condition_value 条件
DECLARE handler_action HANDLER FOR condition_value [,condition_value] ... statement;
handler_action:
- CONTINUE: Continue to execute the current program
- EXIT: terminate the execution of the current program
condition_value :
- SQLSTATE sqlstate_value: status code, such as 02000
- SQLWARNING: Shorthand for all SQLSTATE codes starting with 01
- NOT FOUND: shorthand for all SQLSTATE codes starting with 02
- SQLEXCEPTION: Shorthand for all SQLSTATE codes not caught by SQLWARNING or NOT FOUND
For the sqlstate_value
corresponding status code, you can go to the official MySQL documentation to check
MySQL official documentation: https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html
10. Cursor / Cursor
Cursor (CURSOR) is a data type used to store query result sets. In stored procedures and functions, cursors can be used to cycle through result sets. The use of the cursor includes the declaration of the cursor, OPEN, FETCH and CLOSE, and their syntaxes are as follows.
Declare the cursor:
-- cursor_name 游标名称
-- select_statement 查询语句
DECLARE cursor_name CURSOR FOR select_statement;
Open (OPEN) the cursor:
-- cursor_name 游标名称
OPEN cursor_name;
Fetch (FETCH) cursor records:
-- cursor_name 游标名称
FETCH cursor_name INTO var_name [,var_name] ...
Close (CLOSE) the cursor:
-- cursor_name 游标名称
CLOSE cursor_name
Example:
查询学生数据,并将学生数据插入到所创建的一张新表(name,birth,sex,age,phone_number)中
DELIMITER $
create procedure pro_cursor(in n int)
begin
-- 先声明变量
declare s_name varchar(50);
declare s_birth varchar(50);
declare s_sex varchar(50);
declare s_age varchar(50);
-- 再声明游标
declare s_cursor cursor for select name,birth,sex,age from student where age <= n ;
-- 声明条件处理程序:当状态码为 '02000' 的时候退出,并且关闭掉游标
declare exit handler for SQLSTATE '02000' close s_cursor;
-- 或者:当状态码以 '02' 开头的时候退出,并且关闭掉游标
-- declare exit handler for not found close s_cursor;
-- drop table if exists tb_student_pro;
-- 如果表不存在则创建
create table if not exists tb_student_pro(
id int PRIMARY key auto_increment,
name varchar(50),
birth varchar(50),
sex tinyint(1),
age int(3)
);
-- 开启游标
open s_cursor;
while true do
-- 获取游标记录:一一对应到所声明的字段之中
fetch s_cursor into s_name,s_birth,s_sex,s_age;
-- 插入数据
insert into tb_student_pro values (null,s_name,s_birth,s_sex,s_age);
end while;
-- 关闭游标
close s_cursor;
end$
DELIMITER ;
call pro_cursor(20);
The result of the call is displayed as follows:
And created tb_student_pro
a table , the data in the table is as follows: