start transaction; 开启事务,sql语句并不会立即执行。
。。。。。。。
。。。。。。。此处为SQL语句
commit; 提交事务。执行sql语句,提交后事务无法撤销。
rollback; 回滚,取消事务,前面的语句都不执行。
事务的特性:
原子性:一个事务就是一个不可再分的单元。要么都执行,要么都不执行。
一致性:事务将数据库从一个状态转变为另一个状态,前后数据库状态保持一致。
隔离性:多个用户并发访问数据库,彼此之间隔离。
持久性;事务一旦提交,其做的修改将永久保存到数据库中,无法修改
事务的隔离级别:
每个用户可以自行设置自己的隔离级别。
设置隔离级别语法:
set 【session/global】 transaction 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 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;
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;