MySQL函数、存储过程和触发器

本文详细介绍了MySQL函数、存储过程和触发器。存储过程是编译后存于数据库的SQL语句集,有增强功能、提高效率等优点;函数分系统内置和自定义,可辅助查询;触发器由事件触发,如INSERT、UPDATE和DELETE语句,可自动执行特定操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MySQL函数和存储过程

1 存储过程

1.1 定义
存储过程是(Stored Procedure)一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数来调用执行它(call调用)
1.2 存储过程优点
1.增强了sql语言的功能和灵活性
2.存储过程在第一次编译后再次调用就不需要再编译,比SQL语句执行效率要高(数据库执行动作时都是先编译后执行)
3.直接调用存储过程可执行已经定义好的SQL语句
4.存储过程可以避免开发人员重复编写相同的SQL语句
5.存储过程是在MySQL服务器中存储和执行,可以减少客户端和服务器的数据传输
1.3 语法
\d 标识符
CREATE PROCEDURE proc_name()
BEGIN


END 标识符
\d ;

调用存储过程call proc_name()
1.4 查看当前有哪些存储过程
show procedure status [like ‘proc_name’]
1.5 显示某一个过程的创建的详细信息:
show create procedure proc_name
1.6 存储过程示例
\d c r e a t e p r o c e d u r e c h a x u n ( ) b e g i n s e l e c t s . n a m e , c . c l a s s f r o m s t u d e n t s s j o i n c l a s s e s c o n s . c l a s s i d = c . c l a s s i d ; e n d create procedure chaxun() begin select s.name,c.class from students s join classes c on s.classid=c.classid; end createprocedurechaxun()beginselects.name,c.classfromstudentssjoinclassescons.classid=c.classid;end
\d ;

2 MySQL函数

2.1 定义
实现某个特定功能的模块(代码块),函数可以接受参数、执行操作(例如复杂计算)并将操作结果以值的形式返回
函数在数学中是一种对应关系, 简单地说,因变量y随着变量x的变化而变化,y就是x的函数

存储过程属于特定的函数(不返回参数值)
2.2 函数分类
2.2.1 系统内置函数
系统函数分为数值函数、字符串函数、日期时间函数

数值函数
很多数字处理和数值方面的运算,则可以使用数值函数,如下
ABS() --返回数值的绝对值 (案例的数值例如x)
CEIL() —返回不小于x的最小整数
FLOOR() —返回不大于 x 的最大整数(与CEIL的用法刚好相反)
MOD(x,y) ----返回数字x除以y后的余数:x mod y 相当于%取模
ROUND(X[,Y]) ---- 将数字X四舍五入到指定的小数位数Y
FLOOR(i + RAND() * (j – i)) —获得一个从i到j之间的随机整数
例如:mysql> select floor(1+rand()*5); 产生1到5的随机数

字符串函数

日期函数
YEAR(date) 获得年份
MONTH(date) 获得月份
DAY(date) 获得天
HOUR(date) 获得小时
MINUTE(date) 获得分钟
SECOND(date) 获得秒
NOW() 当前日期和时间
ADDDATE(date,x) 获得x天后的日期
SUBDATE(date,x) 获得x天前的日期
DATEDIFF(date1,date2) 获得2个日期之间的天数
2.2.2 自定义函数
函数定义语法:
\d 标识符
CREATE FUNCTION function_name(参数列表)
RETURNS 返回值类型
BEGIN
routine_body
END 标识符
2.3 函数特点
辅助查询
用途单一简单工作可以写成函数,查询语句就可以使用
可以和SQL结合使用,放到sql语句中就可以使用
查询工作
有返回值,必须要有返回值
一般返回值,只能是1行1列
2.4 函数示例
例1:输入生日返回年龄:
\d c r e a t e f u n c t i o n g e t a g e ( i n b i r t h d a t e ) r e t u r n s d e c i m a l ( 8 , 2 ) b e g i n r e t u r n ( s e l e c t r o u n d ( d a t e d i f f ( n o w ( ) , i n b i r t h ) / 365 , 2 ) ) ; e n d create function get_age(in_birth date) returns decimal(8,2) begin return(select round(datediff(now(),in_birth)/365,2)); end createfunctiongetage(inbirthdate)returnsdecimal(8,2)beginreturn(selectround(datediff(now(),inbirth)/365,2));end
\d;
select sname,birth,get_age(birth) age from stu;
select sname,birth,get_age(birth) age from stu where get_age(birth)>25;

例2:输入班号返回班名
\d c r e a t e f u n c t i o n g e t c n a m e 1 ( i n c n o i n t ) r e t u r n s v a r c h a r ( 50 ) b e g i n d e c l a r e v c n a m e v a r c h a r ( 50 ) ; s e l e c t c n a m e i n t o v c n a m e f r o m c l a s s w h e r e c n o = i n c n o ; i f v c n a m e i s n o t n u l l t h e n r e t u r n v c n a m e ; e l s e r e t u r n ′ 无 班 ′ ; e n d i f ; e n d create function get_cname1(in_cno int) returns varchar(50) begin declare v_cname varchar(50); select cname into v_cname from class where cno=in_cno; if v_cname is not null then return v_cname; else return '无班'; end if; end createfunctiongetcname1(incnoint)returnsvarchar(50)begindeclarevcnamevarchar(50);selectcnameintovcnamefromclasswherecno=incno;ifvcnameisnotnullthenreturnvcname;elsereturn;endif;end
\d;

select sname,cno,get_cname1(cno) from stu;

例3:输入性别(男|女),体重,身高返回 体态描述
\d c r e a t e f u n c t i o n g e t b m i ( i n s e x v a r c h a r ( 10 ) , i n w e i g h t d e c i m a l ( 4 , 1 ) , i n h e i g h t d e c i m a l ( 4 , 1 ) ) r e t u r n s v a r c h a r ( 20 ) b e g i n r e t u r n ( s e l e c t b n a m e f r o m b m i w h e r e i n w e i g h t / ( i n h e i g h t / 100 ∗ i n h e i g h t / 100 ) b e t w e e n l v a l a n d h v a l a n d s e x = i n s e x ) ; e n d create function get_bmi(in_sex varchar(10), in_weight decimal(4,1), in_height decimal(4,1)) returns varchar(20) begin return(select bname from bmi where in_weight/(in_height/100*in_height/100) between lval and hval and sex=in_sex); end createfunctiongetbmi(insexvarchar(10),inweightdecimal(4,1),inheightdecimal(4,1))returnsvarchar(20)beginreturn(selectbnamefrombmiwhereinweight/(inheight/100inheight/100)betweenlvalandhvalandsex=insex);end
\d;

select sname,sex,height,weight,get_bmi(sex,weight,height) bname from stu;
例4
\d c r e a t e f u n c t i o n g e t c l a s s n a m e ( i n s t u i d i n t ) r e t u r n s v a r c h a r ( 30 ) b e g i n r e t u r n ( s e l e c t c . c l a s s f r o m s t u d e n t s s j o i n c l a s s e s c o n s . c l a s s i d = c . c l a s s i d w h e r e s . s t u i d = i n s t u i d ) ; e n d create function get_class_name(in_stuid int) returns varchar(30) begin return(select c.class from students s join classes c on s.classid=c.classid where s.stuid=in_stuid); end createfunctiongetclassname(instuidint)returnsvarchar(30)beginreturn(selectc.classfromstudentssjoinclassescons.classid=c.classidwheres.stuid=instuid);end
\d;

3 触发器

3.1 定义
触发器(trigger),也叫触发程序,是与表有关的命名数据库对象,触发器是一种特殊的存储过程,但是触发器不需要语句调用,也不需要手动启动,它由事件触发,事件包括INSERT,UPDATE,和DELETE语句,当指定表发生指定动作,将激活触发器。
3.2 触发器语法
CREATE
TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
trigger_body

trigger_time: { BEFORE | AFTER }
before 在触发事件之前执行触发器中的代码
after 在触发事件之后执行触发器中的代码
trigger_event: { INSERT | UPDATE | DELETE }
MySQL支持的触发事件是:增删改DML语句
3.3 NEW和OLD关键字
关键字 insert delete update
new.column_name 引用插入行中的某个列的数值 无 引用更新行中某个列原来的值(更新前的值)
old.column_name 无 引用删除行中某个列的数值 引用更新行中某个列新的值(更新后的值)

3.4 触发器其他相关命令
(1)查看触发器
show triggers;

select * from information_schema.triggers\G;
(2)删除触发器
drop trigger trigger_name;
(3)修改MySQL的语法结束符。
DELIMITER || 将语法分割符修改为||

3.5 示例
创建用户和黑名单表,
用户表:用户编号,手机号,余额;
黑名单表:用户编号,手机号。
如果话费余额不足10元,把用户编号和其手机加入到黑名单表中;如果用户充值后,余额超过10元,把其信息从黑名单表中移除。

\d $$
create trigger t_oper_blacklist before update on users for each row
begin
if new.balance<10 then
insert into blacklist values(old.id,old.phone);
end if;

if new.balance>=10 then
delete from blacklist where id=old.id;
end if;
end$$
\d;

update users set balance=balance-25 where phone=‘18520151234’;
select * from users;
select * from blacklist;

update users set balance=balance+100 where phone=‘18520151234’;
select * from users;
select * from blacklist;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值