Mysql_事务_存储过程_触发器
阅读原文时间:2022年04月04日阅读:1

一、什么是事务?

    事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transaction和end transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。

      概念:例如:在关系数据库中,一个事务可以是一条SQL语句,一组SQL语句或整个程序。

      特性

        事务是恢复和并发控制的基本单位。

        事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。

        原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。

        一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。

        隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

        持久性(durability)。持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

      BEGIN 或 START TRANSACTION 显式地开启一个事务;

      COMMIT 也可以使用 COMMIT WORK,不过二者是等价的。COMMIT 会提交事务,并使已对数据库进行的所有修改成为永久性的;

      ROLLBACK 也可以使用 ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;

      SAVEPOINT identifier,SAVEPOINT 允许在事务中创建一个保存点,一个事务中可以有多个 SAVEPOINT;

      RELEASE SAVEPOINT identifier 删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;

      ROLLBACK TO identifier 把事务回滚到标记点;

       SET TRANSACTION 用来设置事务的隔离级别。InnoDB 存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE。

      1、用 BEGIN, ROLLBACK, COMMIT来实现 BEGIN 开始一个事务 ROLLBACK 事务回滚 COMMIT 事务确认

         2、直接用 SET 来改变 MySQL 的自动提交模式: SET AUTOCOMMIT=0 禁止自动提交 SET AUTOCOMMIT=1 开启自动提交

1 CREATE TABLE runoob_transaction_test( id int(5)) engine=innodb; # 创建数据表
2
3 select * from runoob_transaction_test;
4
5 begin; # 开始事务
6
7 insert into runoob_transaction_test value(5);
8
9 insert into runoob_transaction_test value(6);
10
11 commit; # 提交事务
12
13 select * from runoob_transaction_test;

begin; # 开始事务

insert into runoob_transaction_test values(7);

rollback; # 回滚

select * from runoob_transaction_test; # 因为回滚所以数据没有插入

二、什么是存储过程?

    MySQL 5.0 版本开始支持存储过程。

    存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。

    存储过程是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。

     存储过程思想上很简单,就是数据库 SQL 语言层面的代码封装与重用。

      存储过程可封装,并隐藏复杂的商业逻辑。

      存储过程可以回传值,并可以接受参数。

      存储过程无法使用 SELECT 指令来运行,因为它是子程序,与查看 表,数据表或用户定义函数不同。

        存储过程可以用在数据检验,强制实行商业逻辑等。

DELIMITER $$ #后面有提到

1 create procedure testa() #procedure 关键字

2 begin

3 select * from users;
4 select * from orders;

5 end$

DELIMITER $;

call testa(); #查看存储过程

    

1 delimiter $$ #后面有讲
2 create procedure test2()
3 begin
4 -- 使用 declare语句声明一个变量
5 declare username varchar(32) default '';
6 -- 使用set语句给变量赋值
7 set username='xiaoxiao';
8 -- 将users表中id=1的名称赋值给username
9 select name into username from users where id=1;
10 -- 返回变量
11 select username;
12 end$
13 delimiter $;

1 delimiter $$
2 create procedure test4(userId int)
3 begin
4 declare username varchar(32) default '';
5 declare ordercount int default 0;
6 select name into username from users where id=userId;
7 select username;
8 end$
9 delimiter $;

delimiter $$
create procedure test7(in userId int)
begin
declare username varchar(32) default '';
if(userId%2=0)
then
select name into username from users where id=userId;
select username;
else
select userId;
end if;
end$
delimiter $;

delimiter $$
create procedure test9()
begin
declare i int default 0;
while(i<10) do
begin
select i;
set i=i+1;
insert into test1(id) values(i);
end;
end while;
end$

delimiter $;

1 delimiter $$
2 create function getusername(userid int) returns varchar(32)
3 reads sql data -- 从数据库中读取数据,但不修改数据
4 begin
5 declare username varchar(32) default '';
6 select name into username from users where id=userid;
7 return username;
8 end$
9 delimiter $;

三、什么是触发器?

    触发器(数据库原理术语):触发器(trigger)是SQL server 提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,比如当对一个表进行操作( insert,delete, update)时就会激活它执行。触发器经常用于加强数据的完整性约束和业务规则等。 触发器可以从 DBA_TRIGGERS ,USER_TRIGGERS 数据字典中查到。SQL3的触发器是一个能由系统自动执行对数据库修改的语句。

    触发器可以查询其他表,而且可以包含复杂的SQL语句。它们主要用于强制服从复杂的业务规则或要求。例如:您可以根据客户当前的帐户状态,控制是否允许插入新订单。

触发器也可用于强制引用完整性,以便在多个表中添加、更新或删除行时,保留在这些表之间所定义的关系。然而,强制引用完整性的最好方法是在相关表中定义主键和外键约束。如果使用数据库关系图,则可以在表之间创建关系以自动创建外键约束。

    触发器与存储过程的唯一区别是触发器不能执行EXECUTE语句调用,而是在用户执行Transact-SQL语句时自动触发执行。

    此外触发器是逻辑电路的基本单元电路,具有记忆功能,可用于二进制数据储存,记忆信息等。

    触发器的优缺点

        优点:触发器可通过数据库中的相关表实现级联更改。从约束的角度而言,触发器可以定义比CHECK更为复杂的约束。与CHECK约束不同的是,触发器可以引用其他表中的列。例如,触发器可以使用另一个表中的数据来比较更新数据,以及执行其他操作,如修改数据或显示用户定义错误信息。触发器也可以评估数据修改前后的表的状态,并根据其差异采取对策。一个表中的多个同类触发器(INSERT、DELETE或UPDATE)允许采取多个不同的对策以响应同一个修改语句。

        缺点:滥用会造成数据库及应用程序的维护困难。在数据库操作中,可以通过关系、触发器、存储过程、应用程序等来实现数据操作。同时,规则、约束、缺省值也是保证数据完整性的重要保障。如果对触发器过度地依赖,那么将会影响数据库的结构,同时增加了维护的复杂性。

    触发器的作用:

      触发器经常用于加强数据的完整性约束和业务规则等。 触发器创建语法四要素:

        1.监视地点(table)

        2.监视事件(insert/update/delete)

          3.触发时间(after/before)

          4.触发事件(insert/update/delete)

   SQL语法

DELIMITER $$

         CREATE TRIGGER ``.``

         < [ BEFORE | AFTER ] > < [ INSERT | UPDATE | DELETE ] >

         ON [dbo]  #dbo代表该表的所有者

         FOR EACH ROW  #这句话在mysql是固定的  

         BEGIN

           sql语句;

         END $

         DELIMITER $; 

//脚本中有多行,以分号结尾。MySQL默认的行分隔符是 分号,遇到分号,就执行前面一段语句。 脚本中有多行,我们希望不按照分号来一句一句执行,希望一段代码作为一个整体执行。 在脚本最前面加上 delimiter $$ 并且在end后改回分号  delimiter $;

假设存在一张学生表(student),包括学生的基本信息,学号(stuid)为主键。

另外存在一张成绩表(cj),对应每个学生包括一个值。其中number表示序号为主键,自动递增序列。它在插入过程中默认自增。同时假设成绩表中包括学生姓名和学号。

该成绩表目前没有值,先需要设计一个触发器,当增加新的学生时,需要在成绩表中插入对应的学生信息,至于具体math、chinese、english后面由老师打分更新即可

  那么,如何设计触发器呢?

    1.首先它是一个插入Insert触发器,是建立在表student上的;

    2.然后是after,插入后的事件;

    3.事件内容是插入成绩表,主需要插入学生的学号和姓名,number为自增,而成绩目前不需要。

      注意:new表示student中新插入的值。

1 DELIMITER $$
2 create trigger ins_stu
3 after insert on student for each row
4 begin
5 insert into cj ( stu_id, stu_name)
6 values( new.stuid, new.username);
7 end$
8 DELIMITER $;

    

  然后插入数据: insert student values ('eastmount','111111','6','1991-12-05');        同时插入两个数据,触发器正确执行了;

      在MySQL5.7以前,对同一个表相同触发时机的相同触发事件,只能定义一个触发器。例如,对于某个表的不同字段的AFTER更新触发器,只能定义成一个触发器,在触发器中通过判断更新的字段进行相应的处理。所以在创建触发器之前,最好能够查看MySQL中是否已经存在该触发器。

      MySQL中,查看触发器有两种方法,一种是使用SHOW TRIGGERS语句,一种是SHOW CREATE TRIGGERS TRIGGERNAME 查看触发器的详细信息。

有关触发器更加详细的案例和讲解:https://blog.csdn.net/HT412515/article/details/110094411?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164898347016782089327749%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=164898347016782089327749&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-110094411.142^v5^pc_search_result_control_group,157^v4^control&utm_term=%E8%A7%A6%E5%8F%91%E5%99%A8&spm=1018.2226.3001.4187