视图
用途:把复杂重用率高的sql语句编写成sql视图,提供接口给app调用,实现解耦。
语法:
create VIEW 视图名 as SQL语句
例子:
create view teacher_view as select tid from teacher where tname='李平老师';
使用视图:
select * from teacher_view
注:视图一般情况下只能用于查询
触发器
用途:触发器可以定制用户的对表进行【增、删、改】操作前后的行为,当条件成立时 自动触发函数
语法:
create TRIGGER 触发器名 BEFORE/AFTER INSERT/UPDATE/DELETE on 表名 FOR EACH ROW
BEGIN
... -- 需触发的操作
END
例子:
delimiter // -- 更改结束标记为//
create trigger insert_defore_cmd defore insert on cmd for each row
begin
if New.success = 'no' then
insert into errlog(err_cmd,err_time) values(New.cmd,New.sub_time); -- 必须加分号
end if; -- 必须加分号
end// -- 触发器结束
delimiter ; -- 重置结束标记
注:触发器不能用于定制查询语句行为
事务
用途:将多个sql语句作为原子性操作,一旦出现错误,数据库回滚到初始状态,保证数据的一致性。
语法:
begin; -- 开始事务 / start transaction;
... -- 事务操作
commit; -- 执行 / rollback; --回滚
例子:
start transaction;
update user set balance=900 where name='wsb'; #买支付100元
update user set balance=1010 where name='egon'; #中介拿走10元
update user set balance=1090 where name='ysb'; #卖家拿到90元
commit;
begin;
update user set balance=900 where name='wsb'; #买支付100元
update user set balance=1010 where name='egon'; #中介拿走10元
update user set balance=1090 where name='ysb'; #卖家拿到90元
rollback;
注:若事务中触发了触发器,触发器执行失败也会造成事务回滚。
事务一般需要配合异常捕捉机制使用。
存储过程
用途:存储过程中包含了一系列的sql语句,其放在数据库服务器端,通过调用它可以在app上执行一系列的sql语句。是调用数据库T-sql的接口。
补充:app处理数据库数据的方式
#方式一:
MySQL:存储过程
程序:调用存储过程
#方式二:
MySQL:
程序:纯SQL语句
#方式三:
MySQL:
程序:类和对象,即ORM(本质还是纯SQL语句)
方式一: 存储过程的执行速度最快,数据库只一次解析即可实现多次调用,程序松耦合度。但是不灵活,可能需要其他部门配合。
方式二: 纯SQL向数据库发送的命令字节比存储过程多,而且每次调用都需要数据库重新解析,执行速度较慢,程序紧耦合度。优点:灵活,可根据实际情况任意更改功能。
方式三: ORM调用,app需解析ORM语句成纯sql语句,再发送给数据库,执行速度最慢。优点:快速开发,不需要编写复杂的sql语句。
语法:
1.无参
delimiter //
create procedure p1()
BEGIN
select * from blog;
INSERT into blog(name,sub_time) values("xxx",now());
END //
delimiter ;
#在mysql中调用
call p1()
#在python中基于pymysql调用
cursor.callproc('p1')
print(cursor.fetchall())
2.有参
对于存储过程,可以接收参数,其参数有三类:
#in 仅用于传入参数用
#out 仅用于返回值用
#inout 既可以传入又可以当作返回值
delimiter //
create procedure p2(
in n1 int,
in n2 int
)
BEGIN
select * from blog where id > n1;
END //
delimiter ;
#在mysql中调用
call p2(3,2)
#在python中基于pymysql调用
cursor.callproc('p2',(3,2))
print(cursor.fetchall())
in:传入参数
delimiter //
create procedure p3(
in n1 int,
out res int
)
BEGIN
select * from blog where id > n1;
set res = 1;
END //
delimiter ;
#在mysql中调用
set @res=0; #0代表假(执行失败),1代表真(执行成功)
call p3(3,@res);
select @res;
#在python中基于pymysql调用
cursor.callproc('p3',(3,0)) #0相当于set @res=0
print(cursor.fetchall()) #查询select的查询结果
cursor.execute('select @_p3_0,@_p3_1;') #@p3_0代表第一个参数,@p3_1代表第二个参数,即返回值
print(cursor.fetchall())
out:返回值
delimiter //
create procedure p4(
inout n1 int
)
BEGIN
select * from blog where id > n1;
set n1 = 1;
END //
delimiter ;
#在mysql中调用
set @x=3;
call p4(@x);
select @x;
#在python中基于pymysql调用
cursor.callproc('p4',(3,))
print(cursor.fetchall()) #查询select的查询结果
cursor.execute('select @_p4_0;')
print(cursor.fetchall())
inout:既可以传入又可以返回
函数
MySQL内置函数
一.数学函数
round(x,y) 返回参数x的四舍五入的有y位小数的值
rand() 返回0-1之间的随机值
二.聚合函数
avg(col) 返回指定列的平均值
count(col) 返回指定列的个数
min(col) 返回指定列的最小值
max(col) 返回指定列的最大值
sum(col) 返回指定列的所有制的和
group_concat(col) 返回由属于一组的列值连接组合而成的结果,应对group by分组时可能出现的一个对象多条查询数据的情况
ex:select name,group_concat(score) from user_score group by name;
select name,group_concat(score order by score desc separator '_') from user_score group by name; -- 组内分数排序,以_分割
三.字符串函数
char_length(str) 返回字符串长度
concat(str1,str2...) 返回字符串集的拼接,若任意字符串为null 结果为null
concat_ws(separator,str1,str2,...) 返回字符串集以separator为分隔符的拼接,separator为null时 结果为null;字符串为null时被忽略 为空时显示空
conv(n,form_base,to_base) 进制转换
ex:SELECT conv('a',16,2); 表示将 a 由16进制转换为2进制字符串表示
format(x,d) 将数字x的格式转换为'#,###,###.##',四舍五入保留到小数点后d位,并将结果以字符串格式返回
ex:SELECT FORMAT(12332.1,4); 结果为: '12,332.1000'
insert(str,pos,len,newstr) 在str的pos位置替换len长度字符为newstr
left(str,len) 返回str字符串左侧len长度的子字符
lower(str) 变小写
upper(str) 变大写
reverse(str) 返回字符串str反转后的字符
substring(str,pos)
substring(str form pos)
substring(str,pos,len)
substring(str form pos for len)
四.日期和时间函数
now() 返回当前日期和时间
curdate() 返回当前日期 -- 也可以写成currentdate()
curtime() 返回当前时间 -- 也可以写成currenttime()
year(date) 返回日期date的年份(1000~9999)
month(date) 返回date的月份值(1~12)
week(date) 返回date为一年中第几周(0~53)
dayofyear(date) 返回date是一年的第几天(1~366)
dayofmonth(date) 返回date是一个月的第几天(1~31)
dayofweek(date) 返回date所代表的一星期中的第几天(1~7)
hour(date) 返回time的小时值(0~23)
minute(date) 返回time的分钟值(0~59)
FROM_UNIXTIME(ts,fmt) 根据指定的fmt格式,格式化UNIX时间戳ts
DATE_FORMAT(date,format) 根据format字符串格式化date值
五.加密函数
MD5()
计算字符串str的MD5校验和
PASSWORD(str)
返回字符串str的加密版本,这个加密过程是不可逆转的,和UNIX密码加密过程使用不同的算法。
六.流程控制函数
CASE WHEN[test1] THEN [result1]...ELSE [default] END
如果testN是真,则返回resultN,否则返回default
CASE [test] WHEN[val1] THEN [result]...ELSE [default]END
如果test和valN相等,则返回resultN,否则返回default
IF(test,t,f)
如果test是真,返回t;否则返回f
IFNULL(arg1,arg2)
如果arg1不是空,返回arg1,否则返回arg2
NULLIF(arg1,arg2)
如果arg1=arg2返回NULL;否则返回arg1
自定义函数
#!!!注意!!!
# 函数中不要写sql语句(否则会报错),函数仅仅只是一个功能,是一个在sql中被应用的功能
# 若要想在begin...end...中写sql,请用存储过程
例子:
-- 创建函数
delimiter //
create function f5(
i int
)
returns int
begin
declare res int default 0;
if i = 10 then
set res=100;
elseif i = 20 then
set res=200;
elseif i = 30 then
set res=300;
else
set res=400;
end if;
return res;
end //
delimiter ;
-- 删除函数
drop function func_name;
-- 执行函数
# 获取返回值
select UPPER('egon') into @res;
SELECT @res;
# 在查询中使用
select f1(11,nid) ,name from tb2;