存储过程、视图、触发器、函数
存储过程
MySQL数据库在5.0版本后开始支持存储过程,那么什么是存储过程呢?怎么创建、查看和删除存储过程呢?存储过程有什么优点?
1.概念:什么是存储过程:类似于函数(方法),简单的说存储过程是为了完成某个数据库中的特定功能而编写的语句集合,该语句集包括SQL语句(对数据的增删改查)、条件语句和循
环语句等。
查看现有的存储过程
show procedure status;
删除存储过程
drop procedure 存储过程名称;
调用 存储过程
call 存储过程名称(参数1 参数1类型,参数2 参数2类型);
例如: call A(x int , y varchar(20))
存储过程优点:
1、存储过程增强了SQL语言灵活性。存储过程可以使用控制语句编写,可以完成复杂的判断和较复杂的运算,有很强的灵活性;
2、减少网络流量,降低了网络负载。存储过程在数据库服务器端创建成功后,只需要调用该存储过程即可,而传统的做法是每次都将大量的SQL语句通过网络发送至数据库服务器端然后再执行;
3、存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。
4、系统管理员通过设定某一存储过程的权限实现对相应的数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全。
1、体会封装
create procedure p1 () begin select * from 表; select * from ren; end
2、体会参数
create procedure p2(in m int) #(in 入参 out 出参 inout 入参出参) 变量 声明变量类型 begin select * from 表 where 条件; select * from ren where p_sal > m; end
3、体会控制
create procedure p3(in x int,in c char(1)) begin if c ='d' then select * from ren where p_sal >x; elseif select *nmh from ren where p_sal = x; else select * from ren where p_sal <x; end if; end
4、体会循环
示例:计算1-100累加的和,并且返回计算结果
create procedure p4(inout n int) begin declare sum int default 0; ---- 设置总和变量,并且指定初始值0 (第一种:通过default 设置默认值) declare i int; ---- 声明变量 set i = 0; ---- 通过set为变量设置值(第二种:通过set 给变量 赋值 注意:set赋值,所有的set要放到declare之后( (先声明所有变量,再给所有变量赋值) while i<=n DO ---- 开始循环 set sum = sum +i; set i = i+1; end while; ---- 结束循环 select sum; ---- 提供结果 set n = sum; -----将计算结果提供给 输出变量 n; end;
调用:
-- 调用: set @n = 100; #@ 保持变量不释放 call p4(@n); select @n;
可能遇到的问题:
解决办法:decalre 变量 #声明变量要 写在所有代码的前面
delimiter:
delimiter // # mysql遇到";"就立即执行,为了输入多行代码,临时把";"改成其他符号 create procedure p1(in n1 int, inout n3 int, out n2 int) begin declare temp1 int; # 声明变量temp1 declare temp2 int default 0; select * from v1; set n2 = n1 + 100; # 给n2赋值 set n3 = n3 + n1 + 100; # 给n3赋值 end // delimiter ;
视图
视图概念:
视图是一个虚拟表,其内容由查询定义。
同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自定义视图的查询所引用的表,并且在引用视图时动态生成。
视图好处:
a、简化表之间的联结(把联结写在select中);
b、适当的利用视图可以更清晰地表达查询
c、过滤不想要的数据(select部分)视图能够对机密数据提供安全保护
d、使用视图计算字段值,如汇总这样的值。
1、创建视图
1. create view 视图表 as sql查询语句 2. CREATE view ren_view as select p_id,p_name,p_age,p_leader from ren;
2、使用视图
select * from 视图表 where 条件;
3、更新视图数据
update 视图表 set 字段1='xx' where 条件; 例子:update ren_view set p_age =99 where p_id = 'p004';
4、删除视图数据
delete from 视图表 where 条件; 例子:delete from ren_view where p_id = 'p010';
5、删除视图
drop view 视图表
例子:drop view ren_view;
触发器
触发器(trigger):监视某种情况,并触发某种操作。
触发器创建语法四要素:
1.监视地点(table)
2.监视事件(insert/update/delete)
3.触发时间(after/before)
4.触发事件(insert/update/delete)
1、创建触发器语法
create trigger triggerName after/before insert/update/delete on 表名 for each row #这句话是固定的 begin #需要执行的sql语句 end
注意1:after/before: 只能选一个 ,after 表示 后置触发, before 表示前置触发
注意2:insert/update/delete:只能选一个
示例: 创建 goods order_table 表
# 商品表 create table goods( id int primary key auto_increment, name varchar(20), num int ); #订单表 create table order_table( oid int primary key auto_increment, gid int, much int );
插入数据 : 步骤 略.......
创建触发器:(监视插入)
(新插入订单信息)
create trigger tg1 after insert on order_table for each row begin update goods set num = num-new.much where id = new.gid; end ##对于insert而言,新插入的行用new来表示,行中的每一列的值用new.列名来表示。
现在插入一条订单信息:
insert into order_table(gid,much) values(2,3) #(num = new.3 where id = new.2)
衣服数量由5变成2
-----
修改和删除类似
修改:
create trigger tg1 after update on order_t for each row begin update goods set num=num + old.much - new.much where gid = new.gid; end update order_t set much=5 where oid=3;
删除:
create trigger tg1 after delete on order_t for each row begin update goods set num = num + old.much where gid = old.gid; end delete from order_t where oid=3;
删除触发器:
drop trigger triggerName;
例子:drop trigger tg1;
函数
MySQL提供的内建函数
sum min max char_length concat concat_ws substring conv at # 等等。。。
1、字符串长度:
select char_length(str); select char_length('中国'); # 长度 2 字符 select length(str); select length('中国'); #长度 6 字节
2、字符串拼接:
select concat(str1,str2,..); # (主要用在数据库迁移上) select concat('a','中国',1); # a中国1 select concat('a','中国',1,null); # null PS:如果有任何一个参数是Null, 则返回null
-
select concat_ws(separator,str1,str2,...) # separator 代表分隔符 (自定义连接符) select concat_ws('*','a','中国',1); # a*中国*1 select concat_ws('*','a', ' ' ,1); # a**1 PS:如果有 ' ' 空字符串, 不会忽略 select concat_ws('*','a',null,1); # a*1 PS:如果有 null ,会忽略所有的 null
3、字符串截取:
select substring(); select substring(str, pos) #pos 起始位置 select substring('hellworld' , 2); # ellworld select substring(str from pos) select substring('hellworld' from 2); # ellworld select substring(str, pos, len) #len 返回的长度 select substring('hellworld', 2, 4); # ellw select substring(str from pos for len) select substring('hellworld' from 2 for 4) # ellw 注意:这4个其实就是2个, 带from 和 for 的是标准SQL语法 pos:负值 从后面计算 起始位置 select substring('hellworld' from -2); # orld select substring('hellworld' from -4 for 3) # orl
4、进制转换:
select conv(N,from_base,to_base) # N:将要被转换的 进制数 from_base:当前进制 to_base:目标进制 select conv(10,10,2) #1010 select conv('A',16,2) #1010
5、格式化输出:
select format(X,D) # X:数字 D:保留位数 select format(5555.5555,2) #5,555.56 PS: 四舍五入 保留2位 select format(5555.5555,0) #5,556 PS: 四舍五入 保留0位 PS:将结果以字符串的形式返回
6、指定位置替换字符串:
select insert(str,pos,len,newstr) str: 在 str 中插入 pos:从第几个位置开始替换(起始位置) len:替换的长度(打算替换掉几个字符) newstr:替换的新字符串 select insert('helloworld',2,8,'www') # hwwwd PS:从第2个位置开始,把elloworl 8个字符串替换 成新的 www select insert('helloworld',2,100,'www') #hwww PS:100个长度,本来就只有9个字符,超出就按完全替换 select insert('helloworld',100,8,'www') #helloworld PS:起始位置超出字符串本身长度,就插入不了,返回还是原字符串 特别的: 如果pos超过原字符串长度,则返回原字符串 如果len超过原字符串长度,则由新字符串完全替换
7、打印当前日期时间:
select curdate() # 2016-12-13 select curtime() # 19:08:36 select now() # 2016-12-13 19:08:43
8、根据 fromat字符串 格式化date值:
select date_format( date , format ) select date_format('2009-10-04 22:23:00', '%W %M %Y') # Sunday October 2009 select date_format('2009-10-04 22:23:00', '%Y年%m月%d') # 2009年10月04 select date_format('2009-10-04 22:23:00', '%D %y %a %d %m %b %j') # 4th 09 Sun 04 10 Oct 277 format字符串 中可以加入汉字 select date_format(now(),'%Y年%m月%d') #2017年11月5
select date_format(ctime,'%Y年%m月%d日%k时%I分%s秒') from users;
https://blog.csdn.net/kangbrother/article/details/7030304
更多函数: 官方猛击这里
INSTR(str,substr) # 返回字符串 str 中子字符串的第一个出现位置。 LEFT(str,len) # 返回字符串str 从开始的len位置的子序列字符。 LOWER(str) # 变小写 UPPER(str) # 变大写 LTRIM(str) # 返回字符串 str ,其引导空格字符被删除。 RTRIM(str) # 返回字符串 str ,结尾空格字符被删去。 SUBSTRING(str,pos,len) # 获取字符串子序列 LOCATE(substr,str,pos) # 获取子序列索引位置 REPEAT(str,count) # 返回一个由重复的字符串str 组成的字符串,字符串str的数目等于count 。 # 若 count <= 0,则返回一个空字符串。 # 若str 或 count 为 NULL,则返回 NULL 。 REPLACE(str,from_str,to_str) # 返回字符串str 以及所有被字符串to_str替代的字符串from_str 。 REVERSE(str) # 返回字符串 str ,顺序和字符顺序相反。 RIGHT(str,len) # 从字符串str 开始,返回从后边开始len个字符组成的子序列 SPACE(N) # 返回一个由N空格组成的字符串。
select rand() # 0--1之间随机一个数字 加入数字