mysql储存过程写法 mysql存储过程语法

概述在数据库的开发过程中 。经常会遇到复杂的业务逻辑和对数据库的操作 。这个时候就会用存储过程来封装数据库操作 。如果项目的存储过程较多 。书写又没有一定的规范 。将会影响以后的系统维护困难和大存储过程逻辑的难以理解 。另外如果数据库的数据量大或者项目对存储过程的性能要求很 。就会遇到优化的问题 。否则速度有可能很慢 。一个经过优化过的存储过程要比一个性能差的存储过程的效率甚至高几百倍 。
未优化的存储过程:

mysql储存过程写法 mysql存储过程语法

文章插图
在存储过程中使用到的表tb_testnum结构如下:

mysql储存过程写法 mysql存储过程语法

文章插图
在存储过程中使用到的另外一张表tb_testnum_tmp结构如下:

mysql储存过程写法 mysql存储过程语法

文章插图
从两个表的结构可以看出 。tb_testnum和tb_testnum_tmp所包含的字段完全相同 。存储过程pr_dealtestnum的作用是根据输入参数将tb_testnum_tmp表的数据插入到tb_testnum表中 。
优化一存储过程pr_dealtestnum的主体是一条insert语句 。但这条insert语句里面又包含了select语句 。这样的编写是不规范的 。因此把这条insert语句拆分成两条语句 。即先把数据从tb_testnum_tmp表中查找出来 。再插入到tb_testnum表中 。修改之后的存储过程如下:
【mysql储存过程写法 mysql存储过程语法】
mysql储存过程写法 mysql存储过程语法

文章插图
优化二在向tb_testnum表插入数据之前 。要判断该条数据在表中是否已经存在了 。如果存在 。则不再插入数据 。同理 。在从tb_testnum_tmp表中查询数据之前 。要先判断该条数据在表中是否存在 。如果存在 。才能从表中查找数据 。修改之后的存储过程如下:
dropprocedureifexistspr_dealtestnum;delimiter//createprocedurepr_dealtestnum(inp_boxnumbervarchar(30))pr_dealtestnum_label:begindeclarep_usertypeint;declarep_datacountint;selectcount(*)intop_datacountfromtb_testnum_tmpwhereboxnumber=p_boxnumber;ifp_datacount>0thenbeginselectusertypeintop_usertypefromtb_testnum_tmpwhereboxnumber=p_boxnumber;end;elsebeginleavepr_dealtestnum_label;end;endif;selectcount(*)intop_datacountfromtb_testnumwhereboxnumber=p_boxnumber;ifp_datacount=0thenbegininsertintotb_testnumvalues(p_boxnumber,p_usertype);leavepr_dealtestnum_label;end;elsebeginleavepr_dealtestnum_label;end;endif;end;//delimiter;select'createprocedurepr_dealtestnumok';优化三不管向tb_testnum表插入数据的操作执行成功与否 。都应该有一个标识值来表示执行的结果 。这样也方便开发人员对程序流程的追踪和调试 。也就是说 。在每条leave语句之前 。都应该有一个返回值 。我们为此定义一个输出参数 。修改之后的存储过程如下:
dropprocedureifexistspr_dealtestnum;delimiter//createprocedurepr_dealtestnum(inp_boxnumbervarchar(30),outp_resultint--0-succ,other-fail)pr_dealtestnum_label:begindeclarep_usertypeint;declarep_datacountint;selectcount(*)intop_datacountfromtb_testnum_tmpwhereboxnumber=p_boxnumber;ifp_datacount>0thenbeginselectusertypeintop_usertypefromtb_testnum_tmpwhereboxnumber=p_boxnumber;end;elsebeginsetp_result=1;leavepr_dealtestnum_label;end;endif;selectcount(*)intop_datacountfromtb_testnumwhereboxnumber=p_boxnumber;ifp_datacount=0thenbegininsertintotb_testnumvalues(p_boxnumber,p_usertype);setp_result=0;leavepr_dealtestnum_label;end;elsebeginsetp_result=2;leavepr_dealtestnum_label;end;endif;end;//delimiter;select'createprocedurepr_dealtestnumok';优化四“insert into tb_testnum values(p_boxnumber,p_usertype);”语句中 。tb_testnum表之后没有列出具体的字段名 。这个也是不规范的 。如果在以后的软件版本中 。tb_testnum表中新增了字段 。那么这条insert语句极有可能会报错 。因此 。规范的写法是无论tb_testnum表中有多少字段 。在执行insert操作时 。都要列出具体的字段名 。修改之后的存储过程如下:
dropprocedureifexistspr_dealtestnum;delimiter//createprocedurepr_dealtestnum(inp_boxnumbervarchar(30),outp_resultint--0-succ,other-fail)pr_dealtestnum_label:begindeclarep_usertypeint;declarep_datacountint;selectcount(*)intop_datacountfromtb_testnum_tmpwhereboxnumber=p_boxnumber;ifp_datacount>0thenbeginselectusertypeintop_usertypefromtb_testnum_tmpwhereboxnumber=p_boxnumber;end;elsebeginsetp_result=1;leavepr_dealtestnum_label;end;endif;selectcount(*)intop_datacountfromtb_testnumwhereboxnumber=p_boxnumber;ifp_datacount=0thenbegininsertintotb_testnum(boxnumber,usertype)values(p_boxnumber,p_usertype);setp_result=0;leavepr_dealtestnum_label;end;elsebeginsetp_result=2;leavepr_dealtestnum_label;end;endif;end;//delimiter;select'createprocedurepr_dealtestnumok';

推荐阅读