视图(view)
虚拟存在的表,不保存查询结构,只保存查询的sql逻辑
语法
存储过程
实现定义并存储在数据库的一段sql语句的集合,可减少网络交互,提高性能,代码复用,内容包括:变量,if,case,参数(in/out/inout),循环(while,repeat,loop),游标和handler。
存储过程-基本语法
create和call
create procedure p1()
begin select count(*) from course;
end;
#调用
call p1();
存储过程-系统变量
#系统变量
show session variables ; #查看所有系统变量
show session variables like 'auto%';(等价于 show global variables like 'auto%';)
select @@session.autocommit;#查看指定系统变量
set session autocommit=0;#设置系统变量,关闭自动提交
存储过程-局部变量
局部变量是存在于存储过程中的,通过declare声明局部变量,同时可以在存储过程中给局部变量赋值
#局部变量
create procedure p2()
begindeclare stu_count int default 0;#说明select count(*) into stu_count from student;#赋值select stu_count;#查询
end;
call p2();
存储过程-用户自定义变量
定义用户变量用@
#用户变量
#赋值方式一:推荐使用:=
set @myname='itcast';
set @myage:=10;
set @mygender:='男',@myhobby:='java';
#赋值方式二:通过select
select @mycolor:='red';
select count(*) into @mycount from student;
#查看
select @myage,@myname;
存储过程-参数(in,out,inout)
#存储过程参数 in:该类参数作为输入,也就是需要调用时传入值 # out:该类参数作为输出,也就是该参数可以作为返回值 # inout:既可以作为输入参数,也可以作为输出参数
#存储过程参数 in:该类参数作为输入,也就是需要调用时传入值
# out:该类参数作为输出,也就是该参数可以作为返回值
# inout:既可以作为输入参数,也可以作为输出参数create procedure p4(in score int,out result varchar(10))
beginif score>=85 thenset result:='优秀';elseif score>=60 thenset result:='及格';elseset result:='不及格';end if;
end;
call p4(99,@result);
select @result;create procedure p5(inout score int)
beginset score:=score*0.5;
end;
#注意点:out和inout需要传的是变量,不能直接传值!!
set @score=200;
call p5(@score);
select @score;
存储过程-case
存储过程-while循环
存储过程-repeat循环
存储过程-loop循环
loop循环和leave,iterate关键字配合使用,leave终止循环(相当于break),iterate结束本次循环(相当于continue)
下面例子 计算的是从1加到10的偶数的和
/*
loop循环leave:配合循环使用,退出循环iterate:必须用在循环中,作用是跳过当前循环剩下的语句,直接进入下一次
*/
create procedure p10(in n int)
begindeclare total int default 0;sum:loopif n<=0 thenleave sum;end if;if n%2=1 thenset n:=n-1;iterate sum;end if;set total:=total+n;set n:=n-1;end loop sum;select total;
end;
call p10(10)
游标和handler
游标的声明,打开,获取,关闭。游标类似二维数组,又不太像,因为游标获取一条记录就同时向新表插入一条记录。游标声明:从基本表中获取哪些字段数据,游标获取:将游标从基本表中获取的每一组字段插入到新表中
游标语法:
handler类似异常处理,在下面例子中作用是当while循环游标fetch不到下一组数据,反映给handler退出程序。
handler语法:
代码练习
create procedure p1(in uage int)
begindeclare uname varchar(100);declare ujob varchar(100);#注意游标要在变量之后声明declare u_cursor cursor for select name,job from emp where age<=uage;#handler,处理异常# declare exit handler for not found close u_cursor;drop table if exists tb_user_pro;create table tb_user_pro(id int primary key auto_increment,name varchar(100),professsion varchar(100));#打开游标open u_cursor;while true dofetch u_cursor into uname,ujob;#通过游标获取数据insert into tb_user_pro values (null,uname,ujob);end while;#关闭游标close u_cursor;
end;
drop procedure p1;
call p1(30);
存储函数
存储函数是由返回值的存储过程,存储函数的参数只能是in类型
存储函数语法:
代码:
create function f1(n int)returns int deterministic
begindeclare sum int default 0;while n>0 doset sum:=sum+n;set n:=n-1;end while;return sum;
end;select f1(100);
触发器
触发器是和表相关的数据库对象,指的是在对表进行增删改查操作前后触发并执行触发器中定义的sql语句,触发器能保证数据的完整性,分为insert触发器,delete触发器,update触发器
触发器语法
插入触发器
问题:我们要向表tb_user插入数据,希望在日志表中看到插入后的新记录是什么
解决:每向表tb_user插入一次,就执行一次insert触发器中的sql语句
代码
create table user_logs(id int(11) not null auto_increment primary key,operation varchar(20) not null comment '操作类型,增/删/改',operation_time datetime not null comment '操作时间',operation_id int(11) not null comment '操作的id',operation_params varchar(500) comment '操作参数')engine =innodb default charset utf8;-- 插入数据触发器
create trigger tb_user_insert_triggerafter insert on tb_user for each rowbegininsert into user_logs(id, operation, operation_time, operation_id, operation_params)VALUES(null,'insert',now(),new.id,concat('插入的内容为:id=',new.id,',name=',NEW.name,',age=',NEW.age));
end;
show triggers ;
insert into tb_user(id, name, age) VALUES (null,'小何',54);
修改触发器
-- 修改数据触发器
-- 要在日志表中展示修改前后的数据
create trigger tb_user_update_triggerafter update on tb_user for each rowbegininsert into user_logs(id, operation, operation_time, operation_id, operation_params)VALUES(null,'update',now(),new.id,concat('更新前的内容为:id=',OLD.id,',name=',OLD.name,',age=',OLD.age,'更新后的内容为:id=',new.id,',name=',NEW.name,',age=',NEW.age));
end;
show triggers ;update tb_user set name='小林' where id=4;
删除触发器
create trigger tb_user_delete_triggerbefore delete on tb_user for each row
begininsert into user_logs(id, operation, operation_time, operation_id, operation_params)VALUES(null,'delete',now(),OLD.id,concat('删除前的内容为:id=',OLD.id,',name=',OLD.name,',age=',OLD.age));
end;show triggers ;
delete from first.tb_user where id=4;