【MySQL速通篇003】MySQL视图,MySQL触发器,MySQL函数,MySQL存储过程(参数分类,存储过程的增删改查等),SQL的动态执行,支持事务的存储过程,pymysql 1

🍀1、delimiter

概念:

delimiter是用来指定mysql分隔符,在mysql客户端中分隔符默认是分号(;)。如果一次输入的语句较多,并且语句中间有分号, 这时需要新指定一个特殊的分隔符。比如我们指定SQL以(//)结尾而不使用默认的(;)那需要执行下面的语句

delimiter //
记得使用完要改回默认的,因为要防止其他人使用;结尾而发生错误
delimiter ;

🍀2、union 与 union all

union与union all都可以实现上下连表,但是不同的是union 会对新加入的数据进行去重,而union all不会

比如我有一张class表如下:

72d5d29012464257b30d1839f689df54.png

执行如下:

SELECT cid, caption FROM class 
UNION 
SELECT cid, caption FROM class
输出结果去重:
cid caption
1   三年二班
2   三年三班
3   一年二班
4   二年九班
SELECT cid, caption FROM class 
UNION 
SELECT cid, caption FROM class
输出结果不去重:
cid caption
1   三年二班
2   三年三班
3   一年二班
4   二年九班
1   三年二班
2   三年三班
3   一年二班
4   二年九班

🍀3、MySQL视图

什么是视图?

答:先不说概念,首先假设我们在MySQL操作中不断会使用到 SELECT * FROM class WHERE cid>2 这一条语句,那每当我们要使用这条语句的时候,

就要重复书写,这样是十分麻烦的, 那么 我们可不可以将这一句会重复使用到的语句取个别名比如叫**“v666”**,每当我们要使用这条语句的时候只要用它的别名来代替那么就会十分省事, 我们将给MySQL语句取别名的过程就叫做创建视图 相当于基于存在的物理表而创建了一张虚拟表

视图的创建方法:

CREATE VIEW 视图名称 AS 需要取别名的SQL语句
CREATE VIEW v1 AS SELECT * FROM class WHERE cid>2

efad5f21a4d1443dac2e3897508e92b7.png

问题一:如果我们在class表中增加一条数据,基于class表产生的视图中的数据会发生改变吗?

答案:视图中会发生动态的改变

问题二:我们可以向创建出来的视图中(也就是所说的虚拟表)中插入数据吗?例如执行以下的语句

INSERT INTO v1(xx, xx) VALUES(xx,xx) 吗?

答案:都说了视图是创建出来的方便查询的虚拟表,那当然是不可以的如果执行上面的语句是百分百会报错的

🍀4、MySQL触发器

🍁4.1、创建触发器

什么是触发器?

答:触发器(TRIGGER)是由事件来触发某个操作。这些事件包括insert语句、update语句和delete语句查询是不会引发的。 当数据库系统执行这些事件时,就会激活触发器执行相应的操作。比如我有两张表分别为【class】【teacher】比 如我只要在teacher表中插入一条数据,对应的class会触发在表中插入相应的数据,要实现这种关系我们就要使用到触发器

触发器的实现:

实例:

5174c8727db14911ba0513d3aa66fb77.png

🍁4.2、触发器之 NEW与OLD

mysql触发器 中, NEW关键字,和 MS SQL Server 中的 INSERTED 和 DELETED 类似,MySQL 中定义了 NEW 和 OLD,用来表示触发器的所在表中,触发了触发器的那一行数据。

具体地:

在 INSERT 型触发器中,NEW 用来表示将要(BEFORE)或已经(AFTER)插入的新数据;

在 UPDATE 型触发器中,OLD 用来表示将要或已经被修改的原数据,NEW 用来表示将要或已经修改为的新数据;

在 DELETE 型触发器中,OLD 用来表示将要或已经被删除的原数据;

使用方法: NEW.columnName (columnName 为相应数据表某一列名)

另外,OLD 是只读的,而 NEW 则可以在触发器中使用 SET 赋值,这样不会再次触发触发器,造成循环调用。

栗子:

CREATE TRIGGER t1 BEFORE INSERT ON 
teacher FOR EACH ROW INSERT INTO class(caption) values(NEW.tname);//触发器插入的数据为teacher新插入数据的sname

🍁4.3、查看触发器

方式1:查看当前数据库的所有触发器的定义

SHOW TRIGGERS;

方法2: 查看当前数据库中某个触发器的定义

SHOW CREATE TRIGGER 触发器名

方式3:从系统库information_schema的TRIGGERS表中查询触发器的信息

SELECT * FROM information_schema.TRIGGERS;

🍁4.4、删除触发器

DROP TRIGGER  IF EXISTS 触发器名称;

🍀5、MySQL函数

🍁5.1、执行函数

可以用以下语句来执行mysql的内置函数,以及自定义函数

栗子:

🍁5.2、创建函数

mysql创建函数可能会报的错误以及解决的方法:

这是因为创建函数、存储过程、触发器这类操作会写入二进制日志,当有主丛模式的时候这些功能也会进入从服务器,然而这些操作的重复执行会导致主从数据不一致,因此MySQL要求:此时在主服务器上,子程序必须声明为确定性的或者不更改数据,否则创建或者替换子程序就会被拒绝。这就是上面报错的原因,


报错中已经提级可用的参数:DETERMINISTIC, NO SQL, or READS SQL DATA 三者之一,实际有以下5个参数,但在function里面,只有 DETERMINISTIC, NO SQL 和 READS SQL DATA 被支持。如下:

1 DETERMINISTIC 确定的

2 NO SQL 没有SQl语句,不修改数据

3 READS SQL DATA 只读取数据,不修改数据

4 MODIFIES SQL DATA 修改数据

5 CONTAINS SQL 包含SQL语句

原文链接附上非常详细: mysql函数报错解决方法

从上面的栗子我们可以得知函数体内不能够存在类似于select等修改数据的语句

方法如下:

CREATE FUNCTION <函数名> ( [ <参数1> <类型1> [ , <参数2> <类型2>] ] … )
RETURNS <返回类型>

栗子:

delimiter \\
create function f1(
    var1 int,
    var2 int
returns int 
-- 此处加上声明没有SQL语句。才能成功创建函数
NO SQL
begin
    -- 将int变量num的默认值为0
    declare num int default 0;
    set num = var1 + var2;
    -- 设置返回值
    return(num);
end \\
delimiter ;
执行函数:
SELECT f1(1, 2)
输出结果:
--------+
f1(1, 2)
--------+
--------+

🍀6.存储过程

🍁6.0、概念

什么是存储过程?

🍁6.1、参数分类

存储过程的参数类型可以是in、out和inout

下面我们来具体介绍这些吗参数的作用:

🍁6.2、创建存储过程

方法:

栗子:

🍁6.3、调用存储过程

方法:

调用存储过程

输出结果:


875c56eebe6c485f9877efcb3964b4f0.png

格式:

1、调用in模式的参数:

2、调用out模式的参数:

特别的由于存储过程中没有一个类似于return的可返回返回值的关键字,所以我们有结果集以及使用out伪造一个类似于返回值的效果 。@加变量名,相当Python中声明了一个全局变量,存储过程中out变量的改变可以改变外部的@变量名的值,从而得到类似于返回值的效果

栗子下面这个栗子在6.8还要用到:

创建存储过程

执行下面的语句:

9e16bc9090134dd790cd7cdd439002e5.png

3、调用inout模式的参数:


【MySQL速通篇003】MySQL视图,MySQL触发器,MySQL函数,MySQL存储过程(参数分类,存储过程的增删改查等),SQL的动态执行,支持事务的存储过程,pymysql 2
【MySQL速通篇003】MySQL视图,MySQL触发器,MySQL函数,MySQL存储过程(参数分类,存储过程的增删改查等),SQL的动态执行,支持事务的存储过程,pymysql 2
使用事务码 SAT 比较传统的 SELECT SQL 语句和 OPEN / FETCH CURSOR 分块读取 ABAP 数据库表两种方式的性能差异试读版
使用事务码 SAT 比较传统的 SELECT SQL 语句和 OPEN / FETCH CURSOR 分块读取 ABAP 数据库表两种方式的性能差异试读版
目前为止我们已经学习了有一定数量的sql命令和sql语言的概念了。 那么在实际使用过程中,这些语句是一句一句按顺序执行的吗?sql语言也有主流编程语言一样的“顺序结构、循环结构、分支结构”这么一说吗? 其实在实际的业务当中,sql语言可能不会像编程语言那样有三类明显的语句结构。 但是sql中语句语句之间的关系必然也是有的,想象一下银行的转账操作,一个账户扣款和另一个账户的进账必须看作一个整体,少哪个步骤都会造成严重的后果。 这就是sql语言的事务——
什么是事务?一个事务就是一个完整的业务逻辑,就是a转账给b,那么a要扣钱,b要加钱两者需要同时进行。 只有DML的三个语句和事务有关系,其他都没有关系。因为三个语句是数据库表的增删改。只要你的操作一旦涉及到就需要考虑安全问题。 提交事务:清空事务性活动的日志文件,将数据全部