第6章 事务与存储过程电子笔记

  • 事务管理
    事务:对数据的一系列操作,可以使一条,也可以是多条。要么全执行,要么全不执行。
    mysql中自动提价事务,直接书写的sql语句是写一条提交一条。
  start transaction; 开启事务,sql语句并不会立即执行。
   。。。。。。。
  。。。。。。。此处为SQL语句
   commit;   提交事务。执行sql语句,提交后事务无法撤销。
   rollback; 回滚,取消事务,前面的语句都不执行。

事务的特性:
原子性:一个事务就是一个不可再分的单元。要么都执行,要么都不执行。
一致性:事务将数据库从一个状态转变为另一个状态,前后数据库状态保持一致。
隔离性:多个用户并发访问数据库,彼此之间隔离。
持久性;事务一旦提交,其做的修改将永久保存到数据库中,无法修改
事务的隔离级别:
每个用户可以自行设置自己的隔离级别。
设置隔离级别语法:

setsession/globaltransaction isolation level read uncommitted;

查看隔离级别语法:

select @@transaction_isolation;

1.read uncommitted;读未提交。(脏读)—不做任何隔离,具有脏读,不可重复读,虚读(幻读)问题

2.read committed;读提交 --可以防止脏读,不能防止不可重复读,虚读(幻读)问题。

3.repeatable read 可重复读 —可防止脏读和不可重复读。

4.serializable 可串行化。 数据库运行在串行化来实现,所有问题都可以避免,但性能非常低。

  • 存储过程
    存储过程的语法
CREATE PROCEDURE sp_name([proc_parameter])
     [characteristics…]routine_body

案例:通过存储过程,执行查询student表。

delimiter //
   create procedure pro ()
   begin
   select * from student;
   end 
   //
   delimiter ;
  • 变量的使用
    变量的声明(定义变量):
DECLARE var_name[,varname]…date_type[DEFAULT value];

例子:声明变量myvariable,类型为int,默认值为100.

declare myvariable int default 100;

变量的赋值:
1.使用set语句进行赋值。

SET var_name = expr[,var_name = expr];

例子:使用set进行赋值

delimiter //
     create procedure pro1()
      begin
       declare myvariable int default 100;
       set myvariable= myvariable+20;
       select myvariable;
      end //
    delimiter ;

2.使用SELECT…INTO为一个或多个变量赋值。

SELECT col_name[] INTO var_name[] table_expr;

例子:把student表内rose的grade和gender赋值给变量s_grade,s_gender.

delimiter //
     create procedure pro1()
      begin
       declare s_grade float ;
       declare s_gender char(2);
       select grade,gender into s_grade,s_gender from student where name ='rose';
       select s_grade,s_gender;
      end //
    delimiter ;
  • 定义条件和处理程序
    定义条件:指事先定义程序执行过程中遇到的问题。
    语法结构:
DECLARE condition_name CONDITION FOR [condition_type];

其中condition_type的两种形式:
1.SQLSTATE[VALUE] sqlstate_value 长度为5的字符串类型的错误代码

 declare  unknowndatabase condition for sqlstate'42000'; 
2.mysql_error_code 数值类型的错误代码
 declare unknowndatabase condition for 1049;

处理程序:定义了在程序执行过程中遇到问题时应当采取的处理方式,并且保证存储过程在遇到警告或错误时能继续执行处理过程。语法结构:

DECLARE handler_type HANDLER FOR condition_value[,] sp_statement

其中handler_type取三种值分别是:
1.continue 遇到错误不处理,继续执行。

declare continue condition for sqlstate'42000';
    2.exit 遇到错误马上退出。
declare exit condition for 1049;
  3.undo 遇到错误后撤回之前的操作。mysql中不支持这种操作

condition_value:错误类型取值:
condition_name 表示定义的条件名称
SQLWARNING 匹配所有以01开头的SQLSTATE错误代码
NOT FOUND 匹配所有以02开头的SQLSTATE错误代码
SQLEXCEPTION 匹配除SQLWARNING和NOT FOUND中外的错误代码
mysql_error_code 匹配数值型错误代码

案例演示:遇到错误继续执行。

CREATE TABLE test(id int,primary key(id));
     
     drop procedure if exists demo;
      DELIMITER //
      CREATE PROCEDURE demo()
      BEGIN
       DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2=1;
       SET @x=1;
       INSERT INTO test VALUES(1);
       SET @x=2;
       INSERT INTO test VALUES(1);
       SET @x=3;
      END  //
      DELIMITER ;

输出结果x的值为3.

  • 光标的使用

光标就是用于处理结果集中的数据,多用于遍历数据。光标声明必须在声明变量、声明定义条件之后,在声明处理程序之前。
光标的声明:

DECLARE cursor_name CURSOR FOR select_statement

光标使用:

OPEN cursor_name   (open c_student)
       FETCH cursor_name INTO var_name[,var_name]close cursor_name   (close c_student)

例:使用光标遍历student表,并将表中的name和gender并复制给s_name,s_gender。

DELIMITER //
      CREATE PROCEDURE demo2()
       BEGIN
        DECLARE s_name varchar(20);
        DECLARE s_gender char(2);
        declare c_student cursor for select name,gender from student;
           open c_student;
           FETCH c_student INTO s_name,s_gender;
        FETCH c_student INTO s_name,s_gender;
        close c_student;
        select s_name,s_gender;
       END  //
      DELIMITER ; 
  • 流程的控制
    if语句:
IF expr_condition THEN statement_list
    [ELSEIF expr_condition THEN statement_list]
    [ELSE statement_list]
    END IF

案例演示:

DELIMITER //
      drop procedure if exists demo3;
      CREATE PROCEDURE demo3()
       BEGIN
        declare val int;
        set val =1;
        if val is null
         then select 'val is null';
        else select 'val is not null';
        end if ;
        END  //
      DELIMITER ; 

case语句:

    (1)CASE case_expr
       WHEN when_value THEN statement_list
      [WHEN when_value THEN statement_list][ELSE statement_list]
      END CASE
    (2)case 
        when expr_condition then  statement_list;
        when expr_condition then  statement_list;
        else statement_list;
       end case 

演示案例:使用case流程控制语句,判断val值等于1、等于2或者两者都不等的情况。

delimiter //
    drop procedure if exists demo3;
    create procedure demo3()
    begin
     declare val int;
     set val=3;
     case val
      when 1 then select'val is 1';
      when 2 then select'val is 2';
      else select 'val is not1 or 2';
     end case ;
    end //
    delimiter ;

loop语句:
用来重复执行某些语句,与if和case相比的话,loop只是创建了一个循环操作的过程,并不进行 判断。

     [loop_label:]LOOP      其中loop_label为标注名称 可以省略
     statement_list
     END LOOP [loop_label]

案例演示:使用loop语句进行循环操作。

 delimiter //
      drop procedure if exists demo3;
      create procedure demo3()
       begin
        declare id int default 0;
        add_loop: loop
        set id= id+1;
            select id;
         if id>=10  then leave add_loop;
         end if;
         
        end loop add_loop;
        
       end //
      delimiter ;

leave语句:
用于退出任何被标注的流程。

leave label    其中label代表循环标志。

iterate语句:
再次循环,用于将执行顺序转到语句段的开头位置。

ITERATE lable

案例演示:用iterate语句在loop语句内的使用。

delimiter //
    drop procedure if exists doiterate;
    CREATE PROCEDURE doiterate()
     BEGIN 
      DECLARE p1 INT DEFAULT 0;
       my_loop:LOOP
        SET p1=p1+1;
         IF p1<10 THEN ITERATE my_loop;
         ELSEIF p1>20 THEN LEAVE my_loop;
         END IF;
        SELECT p1 ;
       END LOOP my_loop;
     END //
    delimiter ;

repeat语句:
用于创建一个有条件判断的循环过程,每次执行完毕都会条件进行判断,如果表达式为真,循环结束,否则重复执行循环过程。

     [repeat_lable:] REPEAT
      statement_list
      UNTIL expr_condition
      END REPEAT[repeat_lable]

案例演示:使用repeat语句执行循环过程

delimiter //
    drop procedure if exists doiterate;
    CREATE PROCEDURE doiterate()
     BEGIN 
      DECLARE id INT DEFAULT 0;
       repeat
        SET id =id+1;
        until id>=10
       end repeat;
       select id;
     END //
    delimiter ;

while语句:
一个带条件判断的的循环语句,与repeat不同,while是先判断后执行,判断为真执行循环,判断为假则退出。repeat 是先执行后判断,真为退出,假为执行循环。

[[while_lable:] WHILE expr_condition DO
          Statement_list
          END WHILE [while_lable]

案例演示:while语句进行循环。

delimiter //
      drop procedure if exists doiterate;
      CREATE PROCEDURE doiterate()
       BEGIN 
        DECLARE id INT DEFAULT 0;
         while id<10 do
          SET id =id+1;
         end while;
         select id;
       END //
      delimiter ;
  • 调用存储过程
    案例演示:创建一个存储过程,然后我们调用它。实现按照我们的条件进行统计数据。
    创建存储过程:
delimiter //
    create procedure countproc2(out num int)
    begin
     select count(*) into num from student ;
    end //
    delimiter ;

调用存储过程:

call countproc2('男',@num);

查看执行结果:

select @num;
  • 查看存储过程
    1.show status 语句
show procedure status [like ‘pattern’]

2.show create 语句

SHOW CREATE{PROCEDURE|FUNCTION} sp_name;

3.information_schema.routines表查看

SELECT * FROM  information_schema.Routines
      WHERE ROUTINE_NAME='countProc2' 
      AND ROUTINE_TYPE='PROCEDURE'\G
  • 修改存储过程
ALTER {PROCEDURE|FUNCTION} sp_name[characteristic…]

案例:修改存储过程countproc2的定义。

alter procedure countproc2 
    modifies sql data
    sql security invoker ;

查看修改后的定义

select  SPECIFIC_NAME,SQL_DATA_ACCESS, SECURITY_TYPE
     from information_schema.routines
     where SPECIFIC_NAME='countproc2' and ROUTINE_TYPE='PROCEDURE';
  • 删除存储过程
DROP{ PROCEDURE|FUNCTION }[IF EXISTS] sp_name

案例演示:删除了countproc2存储过程。

drop procedure countproc2;

你可能感兴趣的:(MySQL数据库入门学习笔记)