Linux数据库管理——day9——视图、存储过程、判断循环

视图
   视图:
      视图是一个虚拟表,可以对视图执行对表的所有操作,只是内容和真实表相似,它并不是在数据库中一存储的信息存在
      每个视图都对应相应的一个或者多个基表,而这基表就是视图中所有数据真正意义上存储的地方

   视图的主要作用
      需要把一个表中几个字段单独列出,方便进行赋权等操作的时候进行操作

   视图的优点
      1. 简单:视图的数据都是过滤好的,查看的时候方便
      2. 安全: 用户只能查看到视图中被过滤的数据,不能看到全局的数据
      3. 数据独立: 一旦视图结构确定,可以屏蔽表机构对用户的影响

   视图的语法

查看当前库下视图信息 show table status where comment='view'\G;
创建视图 create or replace algorithm=算法 view 视图名称 as SQL语句 with check 限制方式 option
就是把SQL查询到的数据创建一个快捷方式,名曰视图,具体选项,下面会详细介绍
删除视图 drop view 视图名
对表的增删改查都可以对视图使用

   创建视图命令详细解释
    1. create or replace 的主要作用是,如果创建过视图,那么下面就是覆盖之前创建的视图结构
    2. algorithm=算法 指定视图检索算法
        这个算法产生的原因是:创建视图的时候,我们使用了一个查询语句,而我们视图也会被再次执行一些SQL语句操作,并且视图并不是真正存储数据的,这时候,我们就需要先后处理这两个语句到基表的数据中,那么这两个语句如何执行就成为了问题,这算法就是解决这个问题的,算法原理如下:

undefined 未定义模式(默认) 当没有指定算法的时候使用这个算法,其算法其实merge算法,所以吧他和替换算法放在一起理解
merge 替换算法 在执行对视图的SQL语句的时候,算法会把创建时候的命令和对视图的命令结合起来,替换成为一个新的语句执行在基表上
temptable 实例算法 执行过程是先根据创建视图时候的查询语句将基表数据提取出来,放入内存中,然后再执行当前对视图的SQL语句

   举个例子:

create view v1 as select r1,r2 from t1;
select r1 from v1;

     若我们这么创建一个视图,并执行下面的查询操作,不同算法执行过程不一样:
     merge替换算法,是把两个select命令(一个是创建时候的)结合成一个命令,执行于基表
     temptable实例算法,是先执行创建时候的select命令把结果放在内存中,然后再以内存中的数据为表进行第二个查询语句

    3. with 限制方式 check option 决定查找范围(主要应用在,基表是视图的情况下)

local 仅检查当前视图限制
cascaded 同时满足基表的限制(默认值)
     举例理解:
create view v1 as select r1,r2 from t1 where r1<100;
create view v2 as select r1 from v1 where r1>30 with local check option
create view v3 as select r1 from v1 where r1>30 with check option

   这时候,我们的v2和v3视图都是基于v1创建的,其中v3没写具体的限制方式,使用的就是cascaded限制方式,v2视图的限制就只有r1>30,而v3的限制就是30<r1<10,具体来说就是:
   如果我们想插入一条数据 r1值为10的值,v2和v3都不能执行,因为他们创建的时候要求r1>30
   如果我们想插入一条数据 r1值为150的值,v2能执行,但v3不能执行,因为v2只检查自己的限制,150满足大于30,所以可以执行,而v2不可以,因为150并不小于100,所以v2不满足
   如果我们想插入一条数据 r1值为50的值,两个视图都可以执行。

   注意: 默认值只是当只写了with check option的时候生效,不写这个命令

   视图不可被修改的情况
      1. 视图创建的时候包含关键字,如SUM、MIN、MAX、COUNT、DISTINCT、GROUP BY、HAVING、UNION、UNION ALL等
      2. 涉及到多表间的操作例如,join或者多表操作的时候
      3. 基表是一个不能被更新的视图

   注意点:
      1. 视图跟着基表中的数据修改而修改,基表跟着视图的数据修改而修改(视图能修改的情况下),视图可以理解为是基表的一个快捷方式,如果修改了视图信息那么表中信息也会变
      2. 视图可以使用多表查询,SQL查询语句查出什么,视图就会创建成什么内容
      3. 创建视图中的SQL查询,其中的select后面的数据可以取别名,而视图中的字段也是以这里取别名的样子出现
      4. 视图不能创建索引,创建的时候不能使用子查询
      5. 可以拿一个视图作为基表,如果只有一个视图,并且该视图可以被修改,那么以这个视图为基表做的视图也是可以进行修改操作的
      6. 如果基表被删除,视图还在,只是数据都不见了,也无法读取视图
ERROR 1356 (HY000): View 'test.view' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
          但是如果之后创建一个同名的表,其中结构满足视图的需求 ,视图又将继续工作


存储过程

   数据库SQL命令的判定执行过程:
     每一条语句,不管多少行,分隔多少次,直到遇到一个分隔符号,才算一个完整的命令,而且只是一条命令,
     在数据库中,命令换行没有任何含义,遇到分隔符算一条命令,一个命令可以写成一行。

   命令delimiter 指定SQL语句运行中的分隔符号,默认为 ;
   为了让存储过程可以完成写完,我们需要修改分隔符号为别的(自己选个不是特殊字符的符号即可,可以由几个组成,例如\\   //  [] ),等后来再改回去即可。 

   创建存储过程基本模板:

delimiter []
create procedure 库名.存储过程名(参数类型  参数名  数据类型  , 参数类型  参数名  数据类型 ……)
begin
    功能代码 ;
    …… 
end[]
delimiter ;

     执行存储过程(如果存储过程要求输入参数,必须在括号内写入相应的数据,详细看下面的调用参数的具体分析)

call  库名.存储过程名();

     删除存储过程

drop procedure 库名.存储过程名;

     查看服务器上的存储过程信息

show procedure status;
select db,name,type,body from mysql.proc where name='存储过程名'; 

    附: 对于存储过程的命令,如果进入了某个具体的库,可以不写库名,就以当前所在库为存储过程所在库。


   变量
    自定义变量:
      设置 set  @变量名=值;

全局变量 查看:show global variables like '%变量名的一部分%'; 如果用set修改变量,那么会影响整个服务器
使用: select @@全局变量名;
通称为系统变量
会话变量
 
设置: set 变量名=值;
查看:show session variables like '%变量名的一部分%'; 如故被修改,只会影响当前连接的整个过程,另开一个连接的时候,变量不会发生变化
用户变量 定义与设置: set @变量名=值; 客户端连接当前数据库的整个过程中有效,和会话变量的区别在于,对数据库性能没有影响
使用: select @变量名;
局部变量 定义:declare 变量名 defaults 默认值; 这是在存储过程中定义变量的方式,只限于这个存储过程的执行过程中,可以理解为脚本中的内部变量
设置: set 变量名=值;


    注意点
      1. 使用select 后面加变量,代表的就是,输出变量值,如果后面加from 表等,不会等效于变量值的查询操作
         举例: select first from table1;   输出的是table1表的first列的所有数据
            但是set a = 'first';    select @a from table1;  输出结果就是按照table1的行数,每行输出的都是first字符串              

     存储过程中调用参数
     定义时候的格式: 参数类型  参数名  数据类型
参数类型

参数类型
in 输入 将执行存储过程中,用户写的参数,赋值给类型后面的参数,并判定是否符合数据类型,如果是变量,执行存储过程中,变量的值可能被修改,但是退出存储过程后,变量还是原来进入存储过程前的值 执行时用户可以输入一个符合要求的具体数值也可以时一个变量
out 输出 不管这个参数也没有数据,开始存储过程的时候,这个变量都会变成空null,然后在存储过程内的语句可以修改整个变量中的值,并在结束存储过程后,变量也是以被修改后的值,前提是变量能被修改 执行时用户必须输入一个可以被修改的变量
inout 输入/输出 结合in和out,执行存储过程中,参数拥有执行前的变量值,在经过存储过程后,参数变量的值也会被修改 执行时用户必须输入一个可以被修改的变量

     注意:
        1. 所有代表参数的变量都可以是空null
        2. 如果变量值变成null,那么就返回的时候也就是null
        3. 参数类型in,参数变量的值会导入到存储过程中,但在执行完存储过程后,返回的时候,其值不会改变
           而参数类型out相反,它的值不会导入到存储过程中,而且以运行存储过程,其值会强制变为空,然后执行存储过程,但执行存储后,返回的时候,其值会根据存储过程中的操作进行修改
           参数类型inout就是结合两个的操作
        4. 如果写成递归,那么创建的时候不会报错,执行的时候会报错,例子如下:

mysql> delimiter []
mysql> create procedure p4(inout x int)
begin
   select x;
   set x=x+1;
   if x<15 then
   call p4(x);
   end if;
end[]
mysql> delimiter ;
mysql> set @x=1;
mysql> call p(@x);
+------+
| x    |
+------+
|   1  |
+------+
1 row in set (0.00 sec)

ERROR 1456 (HY000): Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine p4

    数值运算

+-*/ 四则运算 set @a=@a+1
div 整除运算 set @a=10 div 3 ; 得到结果为3
% 取余运算 set @a=10%3; 得到结果为1

    条件测试

>= > < <= = != 数值比较大小
between .. and .. 在..与..之间
or 、and 、 ! 或 与 非
in 、not in 在范围内 不在范围
is null 为空
like 模糊匹配
regexp 正则匹配

    流程控制

判断语句

if 条件 then
  代码
else
  代码
end if;

循环

while 条件判断 do
  代码
end while;
repeat
  代码
until  条件判断 end repeat;

  while和repeat的区别:
    1. while是先判断后执行,再判断执行…… repeat是先执行一次再判断执行,所以while可能一次不执行,而repeat至少执行一次
    2. while是条件成立执行,repeat是条件成立退出循环

死循环

loop
  代码
end loop;

注意:
      局部变量必须直接写在begin--end内,必须直接写在这个板块中,不能在子模块内,否则会报错
      也就是说循环体内或者判断语句内不能定义变量
 

猜你喜欢

转载自blog.csdn.net/Yu1543376365/article/details/83422219
今日推荐