mysql基础(三)之服务端的其他查询工具


参考博客:http://www.cnblogs.com/wupeiqi/articles/5713323.html
以下视图,触发器,函数,存储过程都是放在mysql的服务端,可以在mysql客户端或pymysql中直接调用它的名字

视图
为某个查询语句(临时表)设置别名,日后方便使用
视图是一个虚拟表,其本质是根据sql语句获取动态的数据集,并为其命名,用户使用时只需使用名称即可
不常用

创建视图: create view t1 as sql语句
修改 alter view t1 as sql语句
删除 drop view t1

使用视图: select * from t1;
触发器
当对某张表做:增删改操作时,可以使用触发器自定义关联行为 before after

delimiter //
create trigger t1 before insert on student for each row
begin
insert into teacher(tname) values(new.sname);
insert into teacher(tname) values(new.sname);
end //
delimiter ;
触发器无法由用户直接使用,而是由对表的操作被动引发的
insert into student(gender,class_id,sname) values('女',1,'陈涛'),('女',1,'陈涛')
删除触发器
drop trigger t1;

new : 代指新数据,进行增,改操作时用到
old : 代指老数据,进行删除操作时用到

函数
内置函数:
官网查询: https://dev.mysql.com/doc/refman/5.7/en/functions.html
执行函数 select curdate();
例如blog
id title ctime
1 asdf 2019-11-8 14:05:03
2 asdf 2019-11-8 14:05:03
3 asdf 2019-10-6 14:05:03
4 asdf 2019-10-5 14:05:03

select ctime,count(1) from blog group ctime 失败
需要进行日期格式化:
select date_format(ctime,'%Y-%m'),count(1) from blog group by data_format(ctime,'%Y-%m')
结果:
2019-11 2
2019-10 2
自定义函数: 有参数和返回值,函数体不能放sql语句
delimiter //
create function f1(
i1 int,
i2 int
)
returns int
begin
declare num int default 0;
set num = i1 + i2;
return(num);
end //
delimiter ;
运行函数:select f1(1,2);


存储过程: 有参数,无返回值,可以放sql语句
存储过程是一个sql语句的集合,当主动去调用存储过程时,其中内部的sql语句会按照逻辑执行
用于替代程序员写sql语句:应用的3中方式:
方式一:
MySQL服务端: 存储过程
程序:调用存储过程
方式二:
MySQL服务端:do nothing
程序:SQL语句
方式三:
MySQL服务端:do nothing
程序:类和对象(SQL语句)
1 简单无参:
delimiter //
create procedure p1()
begin
select * from student;
INSERT into teacher(tname) values("ct");
end
delimiter ;

调用:
mysql客户端 : call p1()
程序调用: cursor.callproc('p1')
2 传参数 (in out inout) inout : 输入实参-----处理----输出参数
delimiter //
create procedure p3(
in n1 int,
inout n2 int
)
BEGIN
set n2 = 123123;
select * from student where sid > n1;
END //
delimiter ;

客户端调用
set @v1=10;
call p3(12,@v1);
select @v1;


程序调用:
cursor.callproc('p3',(12,10))
r1=cursor.fetchall()
print(r1)
cursor.execute('select @_p3_0,@_p3_1')
r2=cursor.fetchall()
print(r2)

3 为什么有结果集又有out伪造的返回值 : 用于标识存储过程的执行结果
事务: out :输入形参
事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性。
伪代码:
delimiter //
create procedure p4(
out status int
)
BEGIN
1. 声明如果出现异常则执行{
set status = 1;
rollback;
}
开始事务
-- 由秦兵账户减去100
-- 方少伟账户加90
-- 张根账户加10
commit;
结束
set status = 2;
END //
delimiter ;

代码:
delimiter \\
create PROCEDURE p5(
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 ;
4 游标: 用于要对数据行中的每一行进行不同的操作(对数据行进行循环遍历)
循环会降低数据库的运行效率,一般不进行循环操作,将数据行取出来之后在程序中进行处理
delimiter //
create procedure p6()
begin
declare row_id int; -- 自定义变量1
declare row_num int; -- 自定义变量2
declare done INT DEFAULT FALSE;
declare temp int;

declare my_cursor CURSOR FOR select id,num from A;
declare CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

open my_cursor;
xxoo: LOOP
fetch my_cursor into row_id,row_num;
if done then
leave xxoo;
END IF;
set temp = row_id + row_num;
insert into B(number) values(temp);
end loop xxoo;
close my_cursor;
end //
delimter ;
6. 动态执行SQL(防SQL注入)
伪代码:
delimiter //
create procedure p7(
in tpl varchar(255),
in arg int
)
begin
1. 预检测某个东西 SQL语句合法性
2. SQL =格式化 tpl + arg
3. 执行SQL语句

set @xo = arg;
PREPARE xxx FROM 'select * from student where sid > ?';
EXECUTE xxx USING @xo;
DEALLOCATE prepare prod;
end //
delimter ;

call p7("select * from tb where id > ?",9)
代码:

delimiter \\
CREATE PROCEDURE p8 (
in nid int
)
BEGIN
set @nid = nid;
PREPARE prod FROM 'select * from student where sid > ?';
EXECUTE prod USING @nid;
DEALLOCATE prepare prod;
END\\
delimiter ;

7 循环
条件语句:
delimiter \\
create procedure pro_if()
begin
declare i int default 0;
if i = 1 then
select 1;
elseif i =2 then
select 2;
else
select 3;
end if
end \\
delimiter ;
循环语句: while
delimiter \\
CREATE PROCEDURE proc_while ()
BEGIN

DECLARE num INT ;
SET num = 0 ;
WHILE num < 10 DO
SELECT
num ;
SET num = num + 1 ;
END WHILE ;

END\\
delimiter ;
循环语句: repeat:
delimiter \\
CREATE PROCEDURE proc_repeat ()
BEGIN

DECLARE i INT ;
SET i = 0 ;
repeat
select i;
set i = i + 1;
until i >= 5
end repeat;

END\\
delimiter ;
循环语句: loop:
BEGIN

declare i int default 0;
loop_label: loop

set i=i+1;
if i<8 then
iterate loop_label;
end if;
if i>=10 then
leave loop_label;
end if;
select i;
end loop loop_label;

END
posted @ 2017-06-18 15:00  柳姑娘  阅读(179)  评论(0编辑  收藏  举报