三. MySQL视图(不常用)
给某个查询语句设置个别名(视图名),日后方便使用
- 创建:
create view 视图名 as SQL;
PS:视图是虚拟的
- 修改:
alter view 视图名 as SQL;
- 删除
drop view 视图名;
create view v1 as select * from student where sid>10;
select * from v1;
student表增加数据,v1视图也会随着增加,不能在v1里面增加数据
四. 触发器(不推荐使用)
# 插入前
CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
BEGIN
...
END
# 插入后
CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW
BEGIN
...
END
# 删除前
CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROW
BEGIN
...
END
# 删除后
CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROW
BEGIN
...
END
# 更新前
CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROW
BEGIN
...
END
# 更新后
CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROW
BEGIN
...
END
五. 函数
内置函数:
执行函数:select CURRENT_DATE();
部分内置函数:
1. CHAR_LENGTH(str)
返回值为字符串str 的长度,长度的单位为字符。一个多字节字符算作一个单字符。
对于一个包含五个二字节字符集, LENGTH()返回值为 10, 而CHAR_LENGTH()的返回值为5。
2. CONCAT(str1,str2,...)
字符串拼接
如有任何一个参数为NULL ,则返回值为 NULL。
...
blog
id title ctime
1 alex1 2017-08-09 11:12
2 alex2 2017-08-03 11:12
3 alex3 2018-11-07 11:12
4 alex4 2018-11-07 11:12
怎么把月份一样的分组?
select ctime,count(1) from blog group DATE_FORMAT(ctime,'%Y-%m')
自定义函数(有返回值):
delimiter \\
create function f1(
i1 int,
i2 int)
returns int
BEGIN
declare num int default 0; 默认为0
set num = i1 + i2;
return(num);
END \\
delimiter ;
select f1(1,100);
六. 存储过程(重要,有可能用的不多)
保存在MySQL上的一个别名 => 一坨SQL语句
使用别名就能查到结果
别名()
用于替代程序员写SQL语句
方式一:(不是很多)
MySQL:存储过程
程序:调用存储过程
方式二:
MySQL:...
程序:SQL语句
方式三:
MySQL:...
程序:类和对象(SQL语句)
创建存储过程:
1. 简单存储过程
delimiter //
create PROCEDURE p1()
BEGIN
SELECT * from student;
insert into teacher(tname) VALUES('ppp');
END //
delimiter ;
call p1(); 执行
python中:cursor.callproc('p1')
2. 传参数(in ,out,inout)
delimiter //
create PROCEDURE p2(
in n1 int,
in n2 int
)
BEGIN
SELECT * from student where sid>n1;
END //
delimiter ;
call p2(12,3); 执行
python 中:cursor.callproc('p2',(12,2))
3. 参数 out
delimiter //
create PROCEDURE p3(
in n1 int,
out n2 int
)
BEGIN
set n2 = 123456;
SELECT * from student where sid>n1;
END //
delimiter ;
set @v1 = 0 ;
call p3(12,@v1)
select @v1; #
set @_p3_0 = 12
set @_p3_1 = 2
call p3(@_p3_0,@_p3_1)
select @_p3_0,@_p3_1;
python中:cursor.execute('select @_p3_0,@_p3_1')
cursor.execute('select @_p3_0,@_p3_1') # 格式就是这样
ret2 = cursor.fetchall()
print(ret2) # ((12, 123456),)
特性:
1. 可传参:in out inout
2. pymysql
cursor.callproc('p3',(12,2))
ret1 = cursor.fetchall()
print(ret1)
cursor.execute('select @_p3_0,@_p3_1')
ret2 = cursor.fetchall()
print(ret2)
为什么有结果集又有out伪造的返回值?
delimiter //
create PROCEDURE p3(
in n1 int,
out n2 int # 用于标识存储过程的执行结果
)
BEGIN
insert into teacher(tname) ...;
insert into teacher(tname) ...;
insert into teacher(tname) ...;
insert into teacher(tname) ...;
insert into teacher(tname) ...;
insert into teacher(tname) ...;
END //
delimiter ;
执行完,不知道执行是否成功。
out:用于标识存储过程的执行结果
4. 事务
伪代码:
delimiter //
create PROCEDURE p4(
out status int
)
BEGIN
1. 声明如果出现异常,则执行(
set status = 1;
rollback;
)
开始事务
-- alex账户减去100
-- egon账户加上90
-- wusir账户加上10
commit;
结束
set status = 2;
END //
delimiter ;
---------------------------------------------------------------------------------------
delimiter \\
create PROCEDURE p1(
OUT p_return_code tinyint
)
BEGIN
DECLARE exit handler for sqlexception
BEGIN
-- ERROR
set p_return_code = 1;
rollback;
END;
START TRANSACTION;
DELETE from tb1;
insert into tb2(name)values('seven');
COMMIT;
-- SUCCESS
set p_return_code = 2;
END\\
delimiter ;