mysql5存储过程实践

分类: Mysql   出处:iocblog整理  更新时间:2010-01-30   添加到收藏  

mysql5.0以后均支持存储过程,最近有空,研究了一把这个
 
格式:
        
create procedure 过程名 ([过程参数[,...]])
    [特性 ...] 过程体

create function 函数名 ([函数参数[,...]])
    returns 返回类型
    [特性 ...] 函数体
    
过程参数:
    [ in | out | inout ] 参数名 参数类型
    
函数参数:
    参数名 参数类型

返回类型:
    有效的mysql数据类型即可

特性:
    language sql
  | [not] deterministic
  | { contains sql | no sql | reads sql data | modifies sql data }
  | sql security { definer | invoker }
  | comment 'string'

过程体/函数体:格式如下:
begin
    有效的sql语句
end    
    
我在这里不关心专有的特性,这些与sql规范不兼容,所以characteristic(特性)的相关内容不作考虑。
//
在开发过程中有几点要注意:
1、存储过程注释:mysql支持采用--或者/**/注释,其中前者是行注释,后者是段式注释
2、变量首先用declare申明,其中临时变量可以直接以@前缀修饰以供引用
3、直接采用mysql的administrator管理器编辑时,可以直接采用如下函数文本录入;
   但若在脚本中自动导入存储过程或函数时,由于mysql默认以";"为分隔符,则过程体的每一句
   都被mysql以存储过程编译,则编译过程会报错;所以要事先用delimiter关键字申明当前段分隔符
   用完了就把分隔符还原。  如下所示:
       delimiter $$
       stored procedures and functions
       delimiter ;
4、mysql支持大量的内嵌函数,有些是和大型商用数据库如oracle、informix、sybase等一致,
   但也有些函数名称不一致,但功能一致;或者有些名称一致,但功能相异,这个特别对于从
   这些数据库开发转过来的dba要注意。
5、存储过程或函数的调试:我目前还没有研究mysql所带的各种工具包,还不清楚其提供了调试工具
   没有,不过编译错误相对好查找;至于业务流程的调试,可以采用一个比较笨的方法,就是创建一
   个调试表,在包体中各个流程点都插入一条记录,以观察程序执行流程。这也是一个比较方便的笨
   办法。^_^
   
   下面是2个例子,提供了一种字串加密的算法,每次以相同的入参调用都会得到不同的加密结果,
   算法相对比较简单,不具备强度。分别以函数和过程的形式分别实现如下:
(1)函数

eg:
create function fun_addmm(inpass varchar(10)) returns varchar(11)
begin
     declare string_in varchar(39);
     declare string_out varchar(78);
     declare offset tinyint(2);
     declare outpass varchar(30) default ';
     declare len tinyint;
     /*declare i tinyint;*/

     /**/
     set len=length(inpass);
     if((len<=0) or (len>10)) then
         return "";
     end if;

     set offset=(second(now()) mod 39)+1; /*根据秒数取模*/
     /*insert into  testtb values(offset,'offset: ');*/
     set string_out='yn8k1jozvurb3mdets5gpl27axwihq94c6f0#$_';  /*密钥*/
     set string_in='_$#abcdefghijklmnopqrstuvwxyz0123456789';

     set outpass=concat(outpass,substring(string_out,offset,1));
/*     insert into  testtb values(2,outpass);*/
     set string_out=concat(string_out,string_out);
     set @i=0;
     repeat
       set @i=@i+1;
       set outpass=concat(outpass,substr(string_out,instr(string_in,substring(inpass,@i,1))+offset,1));
/*       insert into  testtb values(@i+2,outpass);*/
     until (@i>=len)
     end repeat;

     return outpass;
end 


(2)过程

create procedure `pro_addmm`(in inpass varchar(10),out outpass varchar(11))
begin
     declare string_in varchar(39);
     declare string_out varchar(78);
     declare offset tinyint(2);                
     declare len tinyint;

     set outpass=';

     set len=length(inpass);
     if((len<=0) or (len>10)) then
         set outpass=';
     else
         set offset=(second(now()) mod 39)+1;

         set string_out='yn8k1jozvurb3mdets5gpl27axwihq94c6f0#$_';
         set string_in='_$#abcdefghijklmnopqrstuvwxyz0123456789';

         set outpass=concat(outpass,substring(string_out,offset,1));

         set string_out=concat(string_out,string_out);
         set @i=0;
         repeat
               set @i=@i+1;
               set outpass=concat(outpass,substr(string_out,instr(string_in,substring(inpass,@i,1))+offset,1));
         until (@i>=len)
         end repeat;
     end if;
end


//
执行结果如下:
mysql> call pro_addmm('zhouys',@a);
query ok, 0 rows affected (0.00 sec)
(来源www.iocblog.net)
mysql> select @a;
+---------+
| @a      |
+---------+
| u_pi6$4 |
+---------+
1 row in set (0.00 sec)

mysql> call pro_addmm('zhouys',@a);
query ok, 0 rows affected (0.00 sec)

mysql> select @a;
+---------+
| @a      |
+---------+
| 9p8uegm |
+---------+
1 row in set (0.00 sec)

mysql> select fun_submm('u_pi6$4');
+----------------------+
| fun_submm('u_pi6$4') |
+----------------------+
| zhouys               |
+----------------------+
1 row in set (0.00 sec)

加密算法有几个弱点:
1、不支持大小写
2、不支持中文
3、加密强度不够

有兴趣的人可以研究一下解密函数如何编写,这里就不赘述了。
 (来源www.iocblog.net)


Tag: 存储过程



文章整理:iocblog
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。