当前位置:首页 > 资讯 > 正文

mysql撤回执行的上一条语句吗

mysql撤回执行的上一条语句吗


目录

十一、视图

1.常见的数据库对象

2.视图概述

3.创建视图

4.查看视图

5.更新视图

6.修改、删除视图

7.总结

十五、存储过程与函数

1.存储过程概述

2.创建存储过程与调用

3.存储函数概述

4.创建存储函数与调用

5.对比存储过程与存储函数

6.存储过程和函数的查看、修改、删除

7.关于存储过程使用的争议

十六、变量、流程控制与游标

1.变量

2.定义条件与处理程序

3.流程控制

3.1分支结构之IF

3.2分支结构之CASE

3.3循环结构之LOOP

3.4循环结构之WHILE

3.5循环结构之REPEAT

3.6跳转语句之LEAVE语句

3.7跳转语句之ITERATE

4.游标

4.1什么是游标

4.2使用游标的步骤

十七、触发器

1.触发器概述

2.触发器的创建

3.查看和删除触发器

4.触发器的优缺点


为什么使用视图 ?

视图一方面可以帮我们使用表的一部分而不是所有的表,另一方面也可以针对不同的用户制定不同的查询视图。比如,针对一个公司的销售人员,我们只想给他看部分数据,而某些特殊的数据,比如采购的价格,则不会提供给他。再比如,人员薪酬是个敏感的字段,那么只给某个级别以上的人员开放,其他人的查询视图中则不提供这个字段。

视图的理解 :

  • 视图是一种 虚拟表 ,本身是 不具有数据 的,占用很少的内存空间,它是 SQL 中的一个重要概念。
  • 视图建立在已有表的基础上, 视图赖以建立的这些表称为基表
  • 视图的创建和删除只影响视图本身,不影响对应的基表。但是当对视图中的数据进行增加、删除和修改操作时,数据表中的数据会相应地发生变化,反之亦然。
  • 向视图提供数据内容的语句为 SELECT 语句, 可以将视图理解为存储起来的 SELECT 语句
  • 在数据库中,视图不会保存数据,数据真正保存在数据表中。当对视图中的数据进行增加、删除和修改操作时,数据表中的数据会相应地发生变化;反之亦然。
  • 视图,是向用户提供基表数据的另一种表现形式。通常情况下,小型项目的数据库可以不使用视图,但是在大型项目中,以及数据表比较复杂的情况下,视图的价值就凸显出来了,它可以帮助我们把经常查询的结果集放到虚拟表中,提升使用效率。理解和使用起来都非常方便。

视图优点 :

  • 操作简单
  • 减少数据冗余
  • 数据安全
  • 适应灵活多变的需求
  • 能够分解复杂的查询逻辑

视图不足 :

维护性的问题 : 如果基表的结构变更了,我们就需要及时对相关的视图进行相应的维护

如果视图过多,会导致数据库维护成本问题

如果覆盖的视图过多会导致数据不清晰

章节练习

用户自定义的函数。存储过程和函数, 可以将复杂的SQL逻辑封装在一起, 应用程序无需关注存储过程和函数内部复杂的SQL逻辑, 只需要简单的调用存储过程和函数即可。

好处

1、简化操作,提高了sql语句的重用性,减少了开发程序员的压力

2、减少操作过程中的失误,提高效率

3、减少网络传输量(客户端不需要把所有的 SQL 语句通过网络发给服务器)

4、减少了 SQL 语句暴露在网上的风险,也提高了数据查询的安全性

5、相较于函数,存储过程是没有返回值的

分类

存储过程的参数类型可以是IN、OUT和INOUT。根据这点分类如下:

1、没有参数(无参数无返回)

2、仅仅带 IN 类型(有参数无返回)

3、仅仅带 OUT 类型(无参数有返回 )

4、既带 IN 又带 OUT(有参数有返回)

5、带 INOUT(有参数有返回)

注意:IN、OUT、INOUT 都可以在一个存储过程中带多个。

MySQL支持用户自定义的函数, 定义好以后, 调用方式与调用系统预定义的系统函数方式一样。

语法分析

说明:

1、参数列表:指定参数为IN、OUT或INOUT只对PROCEDURE是合法的,FUNCTION中总是默认为IN参数。

2、RETURNS type 语句表示函数返回数据的类型;

RETURNS子句只能对FUNCTION做指定,对函数而言这是 强制 的。它用来指定函数的返回类型,而且函数体必须包含一个 RETURN value 语句。

3、characteristic 创建函数时指定的对函数的约束。取值与创建存储过程时相同,这里不再赘述。

4、函数体也可以用BEGIN…END来表示SQL代码的开始和结束。如果函数体只有一条语句,也可以省略BEGIN…END。

此外,存储函数可以放在查询语句中使用,存储过程不行。反之,存储过程的功能更加强大,包括能够执行对表的操作(比如创建表,删除表等)和事务操作,这些功能是存储函数不具备的。

优点 :

  • 存储过程可以一次编译多次使用
  • 可以减少开发工作量
  • 存储过程的安全性强
  • 可以减少网络传输量
  • 良好的封装性

缺点 :

  • 可移植性差
  • 调试困难
  • 存储过程的版本管理很难
  • 不适合高并发的场景

章节练习

在MySQL数据库的存储过程与函数中,可以使用变量来存储查询或计算的中间结果数据,或者输出最终的结果数据。在MySQL数据库中,变量分为 和。

1.1系统变量

系统变量分类

全局系统变量 和 会话系统变量

全局系统变量是启动服务器之后赋值的系统变量

会话系统变量是建立连接之后(MySQL实例)赋值的系统变量

有的变量既是全局系统变量也是会话系统变量

1.2用户变量

用户变量是自己定义的变量, MySQL中的用户变量以一个 ' @ ' 开头, 根据作用范围不同, 分为会话用户变量和局部变量。

  • 会话用户变量 : 作用域和会话变量一样, 只对当前连接的变量有效
  • 局部变量 : 只在BEGIN 和 END 语句块中有效。局部变量只能在存储过程和函数中使用

是事先定义程序执行过程中可能遇到的问题, 定义了在遇到问题时应当采取的处理方式,并且保证存储过程或函数在遇到警告或错误时能继续执行。这样可以增强存储程序处理问题的能力,避免程序异常停止运行。

说明:定义条件和处理程序在存储过程、存储函数中都是支持的。

2.1案例分析

2.2定义条件

定义条件就是给MySQL中的错误码命名,这有助于存储的程序代码更清晰。它将一个 错误名字 和 指定的 错误条件 关联起来。这个名字可以随后被用在定义处理程序的 DECLARE HANDLER 语句中。

错误码的说明:

  • MySQL_error_code 和 sqlstate_value 都可以表示MySQL的错误。
  • MySQL_error_code是数值类型错误代码。
  • sqlstate_value是长度为5的字符串类型错误代码。

例如,在ERROR 1418 (HY000)中,1418是MySQL_error_code,'HY000'是sqlstate_value。

例如,在ERROR 1142(42000)中,1142是MySQL_error_code,'42000'是sqlstate_value。

2.3定义处理程序

可以为SQL执行过程中发生的某种类型的错误定义特殊的处理程序。定义处理程序时,使用DECLARE语句的语法如下:

处理方式:处理方式有3个取值:CONTINUE、EXIT、UNDO。

  • CONTINUE :表示遇到错误不处理,继续执行。
  • EXIT :表示遇到错误马上退出。
  • UNDO :表示遇到错误后撤回之前的操作。MySQL中暂时不支持这样的操作。

错误类型(即条件)可以有如下取值:

  • SQLSTATE '字符串错误码' :表示长度为5的sqlstate_value类型的错误代码;
  • MySQL_error_code :匹配数值类型错误代码;
  • 错误名称 :表示DECLARE ... CONDITION定义的错误条件名称。
  • SQLWARNING :匹配所有以01开头的SQLSTATE错误代码;
  • NOT FOUND :匹配所有以02开头的SQLSTATE错误代码;
  • SQLEXCEPTION :匹配所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE错误代码;

处理语句:如果出现上述条件之一,则采用对应的处理方式,并执行指定的处理语句。语句可以是

像“ SET 变量 = 值 ”这样的简单语句,也可以是使用 BEGIN ... END 编写的复合语句。

2.4案例解决

解决复杂问题不可能通过一个 SQL 语句完成,我们需要执行多个 SQL 操作。流程控制语句的作用就是控制存储过程中 SQL 语句的执行顺序,是我们完成复杂操作必不可少的一部分。只要是执行的程序,流程就分为三大类:

  • 顺序结构 :程序从上往下依次执行
  • 分支结构 :程序按条件进行选择执行,从两条或多条路径中选择一条执行
  • 循环结构 :程序满足一定条件下,重复执行一组语句

针对于MySQL 的流程控制语句主要有 3 类。注意:只能用于存储程序。

  • 条件判断语句 :IF 语句和 CASE 语句
  • 循环语句 :LOOP、WHILE 和 REPEAT 语句
  • 跳转语句 :ITERATE 和 LEAVE 语句

3.1分支结构之IF

3.2分支结构之CASE

3.3循环结构之LOOP

3.4循环结构之WHILE

3.5循环结构之REPEAT

对比三种循环结构:

这三种循环都可以省略名称,但如果循环中添加了循环控制语句(LEAVE或ITERATE)则必须添加名称。

  • LOOP:一般用于实现简单的"死"循环
  • WHILE:先判断后执行
  • REPEAT:先执行后判断,无条件至少执行一次

3.6跳转语句之LEAVE语句

相当于C语言中的BREAK

LOOP循环语句只能用LEAVE终止循环

LEAVE后面一定加的是标签

3.7跳转语句之ITERATE

相当于java中的continue

只能在循环中使用

小结 :

  • LEAVE 可以使用在循环中和BEGIN END 中 含义为BREAK 跳出循环或存储函数存储过程
  • ITERATE 只能用在循环中 含义为CONTINUE 跳过本次循环
  • 上述两种语法后面必须跟标签名称

4.1什么是游标

虽然我们也可以通过筛选条件 WHERE 和 HAVING,或者是限定返回记录的关键字 LIMIT 返回一条记录,但是,却无法在结果集中像指针一样,向前定位一条记录、向后定位一条记录,或者是 随意定位到某一 条记录 ,并对记录的数据进行处理。

游标可以对结果集中的每一条记录进行定位,游标让SQL这种面向集合的语言有了面向过程的开发能力。

游标在SQL中充当了C语言中指针的作用,可以利用操作游标来对数据行进行操作。

4.2使用游标的步骤

小结 :

游标是 MySQL 的一个重要的功能,为 逐条读取 结果集中的数据,提供了完美的解决方案。跟在应用层面实现相同的功能相比,游标可以在存储程序中使用,效率高,程序也更加简洁。但同时也会带来一些性能问题,比如在使用游标的过程中,会对数据行进行 加锁 ,这样在业务并发量大的时候,不仅会影响业务之间的效率,还会 消耗系统资源 ,造成内存不足,这是因为游标是在内存中进行的处理。

建议:养成用完之后就关闭的习惯,这样才能提高系统的整体效率。

在实际开发中,我们经常会遇到这样的情况:有 2 个或者多个相互关联的表,如 商品信息 和 库存信息 分别存放在 2 个不同的数据表中,我们在添加一条新商品记录的时候,为了保证数据的完整性,必须同时在库存表中添加一条库存记录。

这样一来,我们就必须把这两个关联的操作步骤写到程序里面,而且要用 事务 包裹起来,确保这两个操作成为一个 原子操作 ,要么全部执行,要么全部不执行。要是遇到特殊情况,可能还需要对数据进行手动维护,这样就很 容易忘记其中的一步 ,导致数据缺失。

这个时候,咱们可以使用触发器。你可以创建一个触发器,让商品信息数据的插入操作自动触发库存数据的插入操作。这样一来,就不用担心因为忘记添加库存数据而导致的数据缺失了。

MySQL从 5.0.2 版本开始支持触发器。MySQL的触发器和存储过程一样,都是嵌入到MySQL服务器的一段程序。

触发器是由 事件来触发 某个操作,这些事件包括 INSERT 、 UPDATE 、 DELETE 事件。所谓事件就是指用户的动作或者触发某项行为。如果定义了触发程序,当数据库执行这些语句时候,就相当于事件发生了,就会 自动 激发触发器执行相应的操作。

当对数据表中的数据执行插入、更新和删除操作,需要自动执行一些数据库逻辑时,可以使用触发器来实现。

语法结构

说明:

  • 表名 :表示触发器监控的对象。
  • BEFORE|AFTER :表示触发的时间。BEFORE 表示在事件之前触发;AFTER 表示在事件之后触发。
  • INSERT|UPDATE|DELETE :表示触发的事件。
  • INSERT 表示插入记录时触发;
  • UPDATE 表示更新记录时触发;
  • DELETE 表示删除记录时触发。
  • 触发器执行的语句块 :可以是单条SQL语句,也可以是由BEGIN…END结构组成的复合语句块。

优点 :

  • 触发器可以确保数据的完整性
  • 触发器可以帮助我们记录操作日志
  • 触发器还可以用在操作数据前, 对数据进行合法性的检查

缺点 :

  • 触发器最大的一个问题就是可读性差
  • 相关数据的更新, 可能会导致触发器出错

注意 :

注意,如果在子表中定义了外键约束,并且外键指定了ON UPDATE/DELETE CASCADE/SET NULL子句,此时修改父表被引用的键值或删除父表被引用的记录行时,也会引起子表的修改和删除操作,此时基于子表的UPDATE和DELETE语句定义的触发器并不会被激活

例如:基于子表员工表(t_employee)的DELETE语句定义了触发器t1,而子表的部门编号(did)字段定义了外键约束引用了父表部门表(t_department)的主键列部门编号(did),并且该外键加了“ON DELETE SET NULL”子句,那么如果此时删除父表部门表(t_department)在子表员工表(t_employee)有匹配记录的部门记录时,会引起子表员工表(t_employee)匹配记录的部门编号(did)修改为NULL, mysql> update demo.membermaster set memberdeposit=20 where memberid = 2; ERROR 1054 (42S22): Unknown column 'aa' in 'field list'但是此时不会激活触发器t1。只有直接对子表员工表(t_employee)执行DELETE语句时才会激活触发器t1。