存储过程和函数:
(1)过程:
mysql> delimiter && #设置语句完成符:&&
mysql> create procedure find_age_num(in age int, out age_num int) #procedure定义过程。in是输入参数,out是输出参数,inout输入输出,需要代参数类型
-> reads sql data 这里 language sql:过程使用sql语法(默认);(not) deterministic相同输入(不一定)得到相同输出,默认not deterministic;{contains sql:过程有sql语句,但不读写|no sql:无sql语句|reads sql data:读语句|modifies sql data:包含写语句};sql security{definer定义者才能执行|invoker调用者执行}默认definer;comment '注释'写注释。
-> begin
-> select count(*) into age_num
-> from suremployer
-> where suremployer.age=age;
-> end&&
Query OK, 0 rows affected (0.18 sec)
mysql> delimiter ; #转换符换回来。
(2)函数:
mysql> delimiter &&
mysql> create function name_from_employer(emid int, emname varchar(30)) #function定义函数,参数不能用in,out,inout定义。
-> returns varchar(30) #返回类型
-> reads sql data #和过程一样
-> begin
-> declare tempname varchar(30); #定义一个变量。
-> select name into tempname from suremployer as ot where ot.num=emid;
-> select tempname into emname; #into就是赋值语句。
-> return emname; #返回得到的数据。
-> end&&
mysql> delimiter ;
(3)定义变量:
declare mytemp int default 10; #定义mytemp为int型,初始化为10;没有初始化为空。
赋值:
set mytemp=14;
select 14 into mytemp;
(4)定义条件:就是在过程和函数出错时,对应的处理措施。
declare can_not_find condition for sqlstate '42s02';
declare can_not_find condition for 1146;
1146是mysql_error_code;sqlstate '42s02'是sqlstate_value;两者是一个意思:error 1146(42s02)错误代码是1146,sql状态处于42S02.
declare continue HANDLER FOR SQLSTATE '42S02' SET @info='can not find';
declare exit HANDLER FOR 1146 SET @info='can not find';
DECLARE CONTINUE HANDLER FOR can_not_find SET @info='CAN NOT FIND';
DECLARE EXIT HANDLER FOR SQLWARNING SET @info='ERROR';
DECLARE EXIT HANDLER FOR NOT FOUND SET @info='CAN NOT FIND';
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info='ERROR';
continue/exit/undo(undo在mysql不支持) 遇到错误时的处理;SQLEXCEPTION/NOT FOUND/SQLWARNING/SQLSTATE '42S02'/1146/can_not_find是具体的遇到的错误(can_not_find是定义的条件);SET @info='can not find'是输出错误信息。
#方法一:捕获sqlstate_value
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SET @info='CAN NOT FIND';
#方法二:捕获mysql_error_code
DECLARE CONTINUE HANDLER FOR 1146 SET @info='CAN NOT FIND';
#方法三:先定义条件,然后调用
DECLARE can_not_find CONDITION FOR 1146 ;
DECLARE CONTINUE HANDLER FOR can_not_find SET @info='CAN NOT FIND';
#方法四:使用SQLWARNING
DECLARE EXIT HANDLER FOR SQLWARNING SET @info='ERROR';
#方法五:使用NOT FOUND
DECLARE EXIT HANDLER FOR NOT FOUND SET @info='CAN NOT FIND';
#方法六:使用SQLEXCEPTION
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info='ERROR';
(5)定义光标:就相当于c++中的vector和iterator。如一个int数组(光标集),用以int变量(光标集的每一个)来遍历这个数组的信息。用一个过程来说明:
步骤1:声明光标---------步骤2:打开光标---------步骤3:轮训光标(FETCH)---------步骤4:关闭光标
delimiter $$ --将;结束符改变为$$
--创建存储过程,没有参数
CREATE PROCEDURE payment_amount()
BEGIN
---声明变量
DECLARE i_staff_id int;
--定义一个变量为浮点型,小数位2位,整数位5-2=3位。
DECLARE d_amount decimal(5,2);
---声明一个光标,获取表payment里的staff_id,amount列的值。xxxxxxxxxxxxxxx步骤1:声明光标xxxxxxxxxxxxxxxxxxxx
DECLARE cur_payment cursor for select staff_id,amount from payment;
---条件处理,判断循环结束的条件是 捕获NOT FOUND条件。
---当fecth 找不到下一条记录时,就会关闭光标,退出过程。
DECLARE EXIT HANDLER FOR NOT FOUND CLOSE cur_payment;
--@var是用户自定义变量(user defined vars),@@var是系统变量(system vars),@@var又分成两种:一个是seesion的(local),一个是server的(global)。
--这里就是直接定义变量@x1,@x2并赋值。
set @x1 = 0;
set @x2 = 0;
----打开光标xxxxxxxxxxxxxxx步骤2:打开光标xxxxxxxxxxxxxxxxxxxx
OPEN cur_payment;
--循环开始,REPEAT就是个循环语法。
REPEAT
----轮训光标,循环xxxxxxxxxxxxxxx步骤3:轮训光标xxxxxxxxxxxxxxxxxxxx
FETCH cur_payment INTO i_staff_id,d_amount;
if i_staff_id = 2 then
set @x1 = @x1 + d_amount;
else
set @x2 = @x2 + d_amount;
end if;
--除非遇到0就退出,否则到REPEAT--循环开始下面,有点像代条件的goto语法。
UNTIL 0 END REPEAT;
--关闭光标xxxxxxxxxxxxxxx步骤4:关闭光标xxxxxxxxxxxxxxxxxxxx
CLOSE cur_payment;
END;
$$
delimiter ;
DECLARE定义是有顺序的:变量和条件必须放在前面、然后是光标的声明、最后才可以是 处理程序的声明。
(6)语法:
if语句:
IF age>20 THEN SET @count1=@count1+1;
ELSEIF age=20 THEN @count2=@count2+1;
ELSE @count3=@count3+1;
END IF;
case语句:
CASE age
WHEN 20 THEN SET @count1=@count1+1;
WHEN 21 THEN SET @count3=@count3+1;
ELSE SET @count2=@count2+1;
END CASE ;
或者:
CASE
WHEN age=20 THEN SET @count1=@count1+1;
WHEN age=21 THEN SET @count3=@count3+1;
ELSE SET @count2=@count2+1;
END CASE ;
loop与leave(like c language 'break'),ITERATE(like c language 'continue'):
add_num: LOOP ----循环开始,循环的名称:add_num
SET @count=@count+1;
IF @count=100 THEN
LEAVE add_num ; -----退出循环,相当于break。
ELSE IF MOD(@count,3)=0 THEN
ITERATE add_num; -----进入下个循环,相当于continue。
SELECT * FROM employee ;
END LOOP add_num ;
REPEAT语法:
REPEAT
SET @count=@count+1;
UNTIL @count=100 END REPEAT ;
while,do,end while语法:
WHILE @count<100 DO
SET @count=@count+1;
END WHILE ;
(7)调用过程用CALL:
----过程是找25岁人头数,放到tatol里面,这里@tatol相当于定义一个变量并且可以使用他。
CALL find_age_num(25,@tatol);
打印变量:
select @tatol;
(8)调用储存函数:
----因为返回参数直接可以使用使用一下语句:
----这个函数我有将输出的name防盗@name中,执行完成后我使用select @name为null;
select name_from_employer(201500005,@name);
(9)查看过程和函数:
----看状态。
SHOW { PROCEDURE | FUNCTION } STATUS [ LIKE ' pattern ' ] ;
show function status like 'name%' \G ---这是纵向打印。
show procedure status like 'find_age_num'\G
-----看创建信息。
SHOW CREATE { PROCEDURE | FUNCTION } sp_name ;---跟看表/数据库一样的
show create function name_from_employer;
-----在information_schema.Routines查看。有点想triggers触发器查看一样,在information_schema数据库中保存所有数据库定义的东东,其他了解比较少。
select * from information_schema.ROUTINES where ROUTINE_NAME='name_from_employer' \G
(10)修改过程函数:
-----将过程修改MODIFIES SQL DATA和SQL SECURITY INVOKER属性。
ALTER PROCEDURE num_from_employee MODIFIES SQL DATA SQL SECURITY INVOKER;
ALTER FUNCTION name_from_employee READS SQL DATA COMMENT 'FIND NAME';
(11)删除过程函数:
drop procedure find_age_num;
drop function name_from_employer;
mysql过程函数 mysql过程和函数
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
Mysql 常用函数
Mysql常用函数
mysql 常用函数 mysql函数