存储过程和函数: 

 (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;