2026/3/14 15:00:10
网站建设
项目流程
广西电商网站,室内设计学校专升本,珠海网站制作推广,170个可带链接锚文本外链的网站论坛目录
视图
检查选项
视图更新
存储过程
基本语法
变量操作
条件语句
游标使用
存储函数
触发器 视图
视图#xff1a;(View)是一种虚拟存在的表#xff0c;视图中的数据并不在数据库中实际存在#xff0c;行和列数据来自视图的查询中使用的表#xff0c;并且是在…目录视图检查选项视图更新存储过程基本语法变量操作条件语句游标使用存储函数触发器视图视图(View)是一种虚拟存在的表视图中的数据并不在数据库中实际存在·行和列数据来自视图的查询中使用的表并且是在使用视图时动态生成的。通俗来讲视图只保存了查询的SQL逻辑不保存查询结果所以我们在创建视图的时候主要工作就落在创建这条SQL查询语句上创建视图的语句如下-- 创建视图 create or replace view 视图名称 as select 语句; -- 查询视图 show create view 视图名称; -- 查看创建视图语句 select * from 视图名称; --查看视图数据 -- 修改视图 create or replace view 视图名称 as select 语句; alter view 视图名称 as select 语句; -- 删除视图 drop view if exists 视图名称;通过执行上面对视图操作的语句可以通过如下动图可以看出检查选项当使用with check option子句创建视图时MySQL会通过视图检查正在更改的每个行例如插入、更新、删除以使其符合视图的定义MySQL允许基于另一个视图创建视图它还会检查依赖视图中的规则以保持一致性为了确定检查的范围mysql提供了两个选项cascaded和local默认为cascaded如下所示两者的区别在于都会传递但cascaded不管依赖的试图写没写检查选项都会检查。而local传递后如果没写检查选项就不会检查。视图更新要使视图可更新视图中的行与基础表中的行之间必须存在一对一的关系如果视图包含以下任何一项则该视图不可更新1聚合函数或窗口函数函数SUM()、MIN()、MAX()、COUNT()等2distinct、group by、having、union 或 union all视图作用视图作用主要有以下几个方面1简单视图不仅可以简化用户对数据的理解也可以简化他们的操作那些被经常使用的查询可以被定义为视图从而使得用户不必为以后的操作每次指定全部的条件。2安全数据库可以授权但不能授权到数据库特定行和特定的列上通过视图用户只能查询和修改他们所能见到的数据。3数据独立视图可帮助用户屏蔽真实表结构变化带来的影响。存储过程存储过程是事先经过编译并存储在数据库中的一段SQL语句的集合调用存储过程可以简化应用开发人员的很多工作减少数据在数据库和应用服务器之间的传输对于提高数据处理的效率是有好处的其特点是封装重用可以接受参数也可返回数据减少网络交互并提升效率。简单来说就是数据库SQL语言层面的代码封装与重用如下图所示基本语法存储过程的基本语法如下所示-- 创建 create procedure p1() begin -- 存储过程体 select count(*) from students; -- 查询学生表中的记录数 end; -- 调用 call p1(); -- 查看 select * from information_schema.routines where ROUTINE_SCHEMA mysql_test; -- 查看存储过程 show create procedure p1; -- 查看存储过程的创建信息 -- 删除 drop procedure if exists p1; -- 删除存储过程注意在命令行中执行创建存储过程SQL时需要通过关键字delimiter指定SQL语句的结束符。变量操作在存储过程中除了基本的SQL语法外我们还可以通过变量操作简便我们封装的SQL语句接下来讲解一下在存储过程中的变量操作如下系统变量MySQL服务器提供不属于用户定义属于服务器层面分为全局变量(global)、会话变量(session)两种-- 查看系统变量 show global variables; -- 查看所有全局系统变量 show session variables; -- 查看所有会话系统变量 show global variables like %char%; -- 查看所有与字符集有关的全局系统变量 show session variables like %char%; -- 查看所有与字符集有关的会话系统变量 select global.autocommit; -- 查看全局系统变量名 -- 设置系统变量 set global autocommit0; -- 设置全局系统变量用户定义变量是用户根据需要自己定义的变量用户变量不用提前声明在用的时候直接通过“变量名”使用即可其作用域为当前连接-- 用户变量赋值 set myname zhangsan; set myage : 20; set mygender 男; select count(*) into mycount from tb_user; -- 查询用户表的总记录数, 并赋值给变量 -- 使用变量 select myname, myage, mygender, mycount;局部变量是根据需要定义的在局部生效的变量访问之前需要DECLARE声明可用作存储过程内的局部变量和输入参数局部变量的范围是在其内声明的BEGIN…END块变量类型就是数据库字段类型int、bigint、char、varchar、date、time等-- 局部变量使用 声明declare create procedure p1() begin declare a int default 10; select count(*) into a from students; select a; end; call p1();条件语句在存储过程中除了基本的SQL语法外我们还可以通过条件判断语句简便我们封装的SQL语句接下来讲解一下在存储过程中的条件语句操作如下我们在使用存储过程的存储体中可以通过传递参数动态的实现数据的变化调用参数类型如下类型含义in该类参数作为输入也就是需要调用时传入值out该类参数作为输出也就是该参数可以作为返回值inout既可以作为输入参数也可以作为输出参数这里我们通过if语句进行演示如下if判断语句通过if…else if…else…end if;语句实现-- 方式一 create procedure p1(in score int,out result varchar(10)) begin if score85 then set result优秀; elseif score60 then set result及格; else set result不及格; end if; end; call p1(18, result); select result; -- 方式二 create procedure p2(inout score1 double) begin set score1 : score1*2; end; set score1 : 10; call p2(score1); select score1;case语句 通过case…when…end case;语句实现create procedure p1(in month int) begin declare result varchar(10); case when month 1 and month 3 then set result 春季; when month 4 and month 6 then set result 夏季; when month 7 and month 9 then set result 秋季; when month 10 and month 12 then set result 冬季; else set result 输入错误; end case; select concat(现在是, result); end; call p1(5);while语句while循环是有条件的循环控制语句满足条件后再执行循环体中的SQL语句具体语法如下create procedure p1(in n int) begin declare total int default 0; while n 0 do set total : total n; set n : n - 1; end while; select concat(结果是, total); end; call p1(5);repeat语句是有条件的循环控制语句当满足条件的时候退出循环具体语法为create procedure p1(in n int) begin declare total int default 0; repeat set total : total n; set n : n - 1; until n 0 end repeat; select concat(结果是, total); end; call p1(5);loop语句loop实现简单的循环如果不在SQL逻辑中增加退出循环的条件可以用其来实现简单的死循环loop可以配合一下两个语句使用1leave配合循环使用退出循环2lterate必须用在循环中作用是跳过当前循环剩下的语句直接进入下一次循环create procedure p1(in n int) begin declare total int default 0; sum: loop if n 0 then leave sum; end if; if n%2 1 then set n : n - 1; iterate sum; end if; set total : total n; set n : n - 1; end loop sum; select concat(结果是, total); end; call p1(100);条件处理程序handler可以用来定义在流程控制结构执行过程中遇到问题时相应的处理步骤其具体的语法如下所示游标使用游标(cursor)是用来存储查询结果集的数据类型在存储过程和函数中可以使用游标对结果集进行循环处理游标的使用包括游标的声明、open、fetch和close通过如下案例进行演示根据传入的参数uage来查询员工表emp中所有的用户年龄小于等于uage的用户姓名name和职业job并将用户的姓名和专业插入到所创建的一张新表(id,name,job)中原emp表的内容如下所示create procedure a1(in uage int) begin declare uname varchar(100); -- 声明变量 declare ujob varchar(100); -- 声明变量 -- 声明游标存储查询结果集 declare u_cursor cursor for select name, job from emp where age uage; declare exit handler for sqlstate 02000 close u_cursor; -- 声明退出循环的条件 -- 创建表结构 drop table if exists temp_emp; -- 如果存在则删除 create table if not exists temp_emp( id int primary key auto_increment, name varchar(100), job varchar(100) ); -- 开启游标 open u_cursor; -- 获取游标中的记录 while true do fetch u_cursor into uname, ujob; insert into temp_emp values (null, uname, ujob); end while; -- 关闭游标 close u_cursor; end; call a1(35);执行游标操作之后得到的新表如下所示存储函数存储函数是有返回值的存储过程存储函数的参数只能是IN类型的。具体语法如下create function fun1(n int) returns int deterministic begin declare total int default 0; while n 0 do set total : total n; set n : n - 1; end while; return total; end; select fun1(5);触发器触发器是与表有关的数据库对象指在insert/update/delete之前或之后触发并执行触发器中定义的SQL语句集合触发器的这种特性可以协助应用在数据库端确保数据的完整性日志记录数据校验等操作。使用别名OLD和NEW来引用触发器中发生变化的记录内容这与其他的数据库是相似的现在触发器还只支持行级触发不支持语句级触发触发器的类型如下所示触发器类型new 和 oldinsert型触发器new表示将要或者已经新增的数据update型触发器old表示修改之前的数据new表示将要或已经修改后的数据delete型触发器old表示将要或者已经删除的数据比如说如果我们想对下面这个员工表设置触发器监听表的修改删除更新操作就可以创建一个日志表如下所示插入触发器接下来我们创建一个日志表然后设置一个触发器来监听其插入数据改变的日志记录-- 创建操作日志表 create table emp_logs ( id int(11) not null auto_increment, operation varchar(20) not null comment 操作类型, insert, update, delete, operate_time datetime not null comment 操作时间, operate_id int(11) not null comment 操作人id, operate_params varchar(500) comment 操作参数, primary key (id) ) engine innodb default charset utf8; -- 创建触发器 create trigger tb_emp_insert_trigger after insert on emp for each row begin insert into emp_logs(id, operation, operate_time, operate_id, operate_params) values (null, insert, now(), new.id, concat(插入的数据为id, new.id, , name, ifnull(new.name, 未知), , age, ifnull(new.age, 未知), , salary, ifnull(new.salary, 未知), , enter_date, ifnull(new.enter_date, 未知), , manager_id, ifnull(new.manager_id, 未知) ) ); end; -- 查看触发器 show triggers; -- 删除触发器 drop trigger tb_emp_insert_trigger;然后我们插入一条数据到员工表emp当中-- 测试触发器 insert into emp value (null, 张三12, 20, 主管, 10000, now(), null)可以看到我们的日志已经被成功打印出来了修改触发器修改的触发器可以通过如下的方式进行通过old和new分别拿到更新前后的数据-- 修改数据的触发器 create trigger tb_emp_update_trigger after update on emp for each row begin insert into emp_logs(id, operation, operate_time, operate_id, operate_params) values (null, update, now(), new.id, concat(插入的数据为id, new.id, , name, ifnull(new.name, 未知), , age, ifnull(new.age, 未知), , salary, ifnull(new.salary, 未知), , enter_date, ifnull(new.enter_date, 未知), , manager_id, ifnull(new.manager_id, 未知) ) ); end;删除触发器删除的触发器可以通过如下的方式进行通过old拿到删除后的数据create trigger tb_emp_delete_trigger after delete on emp for each row begin insert into emp_logs(id, operation, operate_time, operate_id, operate_params) values (null, delete, now(), old.id, concat( 删除的数据id, old.id, , name, ifnull(old.name, 未知), , age, ifnull(old.age, 未知), , salary, ifnull(old.salary, 未知), , enter_date, ifnull(old.enter_date, 未知), , manager_id, ifnull(old.manager_id, 未知) ) ); end;