MySQL存储过程实例教程2_第1页
MySQL存储过程实例教程2_第2页
MySQL存储过程实例教程2_第3页
MySQL存储过程实例教程2_第4页
MySQL存储过程实例教程2_第5页
免费预览已结束,剩余12页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、MySQL存储过程详解1 .存储过程简介我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(StoredProcedure是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。一个存储过程是一个可编程的函数,它在数据库中创建并保存。它可以有SQL语句和一些特殊的控制结构组成。当希望在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的。数据库中的存储过程可以看做是对编程中面向对象方法的模拟。它允许控制数据的访问方式。存储过程通常有以下优点:(1) .存储过

2、程增强了SQL语言的功能和灵活性。存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。(2) .存储过程允许标准组件是编程。存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句。而且数据库专业人员可以随时对存储过程进行修改,对应用程序源代码毫无影响。(3) .存储过程能实现较快的执行速度。如果某一操作包含大量的Transaction-SQL代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的。在首次运行一个存储过程时查询,优化器对其进行分析优化,并且给出最终被存储在系统表中的执行计划。而批处理的Transac

3、tion-SQL语句在每次运行时都要进行编译和优化,速度相对要慢一些。(4) .存储过程能过减少网络流量。针对同一个数据库对象的操作(如查询、修改),如果这一操作所涉及的Transaction-SQL语句被组织程存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大增加了网络流量并降低了网络负载。(5) .存储过程可被作为一种安全机制来充分利用。系统管理员通过执行某一存储过程的权限进行限制,能够实现对相应的数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全。2 .关于MySQL的存储过程存储过程是数据库存储的一个重要的功能,但是MySQL在5.0

4、以前并不支持存储过程,这使得MySQL在应用上大打折扣。好在MySQL5.0终于开始已经支持存储过程,这样即可以大大提高数据库的处理速度,同时也可以提高数据库编程的灵活性。3 .MySQL存储过程的创建(1) .格式MySQL存储过程仓ij建的格式:CREATEPROCEDURE过程名(过程参数,.)procedure特性.过程体这里先举个例子:1. mysql>DELIMITER/2. mysql>CREATEPROCEDUREproc1(OUTsint)3. ->BEGIN4. ->SELECTCOUNT(*)INTOsFROMuser;5. ->END6.

5、->/7. mysql>DELIMITER;(1)这里需要注意的是DELIMITER和DELIMITER;两句,DELIMITER是分割符的意思,因为MySQL默认以""为分隔符,如果我们没有声明分割符,那么编译器会把存储过程当成SQL语句进行处理,则存储过程的编译过程会报错,所以要事先用DELIMITER关键字中明当前段分隔符,这样MySQL才会将”当做存储过程中的代码,不会执行这些代码,用完了之后要把分隔符还原。(2)存储过程根据需要可能会有输入、输出、输入输出参数,这里有一个输出参数s,类型是int型,如果有多个参数用",”分割开。(3)过程体的

6、开始与结束使用BEGIN与END进行标识。这样,我们的一个MySQL存储过程就完成了,是不是很容易呢*不懂也没关系,接下来,我们详细的讲解。(2) .声明分割符其实,关于声明分割符,上面的注解已经写得很清楚,不需要多说,只是稍微要注意一点的是:如果是用MySQL的Administrator管理工具时,可以直接创建,不再需要声明。(3) .参数MySQL存储过程的参数用在存储过程的定义,共有三种参数类型,IN,OUT,INOUT,形式如:CREATEPROCEDURE(IN|OUT|INOUT参数名数据类形.)IN输入参数:表示该参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被

7、返回,为默认值OUT输出参数:该值可在存储过程内部被改变,并可返回INOUT输入输出参数:调用时指定,并且可被改变和返回I.IN参数例子创建:1. mysql>DELIMITER/2. mysql>CREATEPROCEDUREdemo_in_parameter(INp_inint)3. ->BEGIN4. ->SELECTp_in;/*查询输入参数*/5. ->SETp_in=2;/*修改*/6. ->SELECTp_in;/*查看修改后的值*/7. ->END;8. ->/9. mysql>DELIMITER;执行结果:1. mysql

8、>SETp_in=1;2. mysql>CALLdemo_in_parameter(p_in);3. +4. |p_in|5. +6. |1|7. +8.9. +10. |p_in|11. +12. |2|13. +14.15. mysql>SELECTp_in;16. +17. |p_in|18. +19. |1|20. +以上可以看出,p_in虽然在存储过程中被修改,但并不影响p_id的值n.out参数例子创建:1. mysql>DELIMITER/2. mysql>CREATEPROCEDUREdemo_out_parameter(OUTp_outint)3

9、. ->BEGIN4. ->SELECTp_out;/*查看输出参数*/5. ->SETp_out=2;/*修改参数值*/6. ->SELECTp_out;/*看看有否变化*/7. ->END;8. ->/9. mysql>DELIMITER;执行结果:1. mysql>SETp_out=1;2. mysql>CALLsp_demo_out_parameter(p_out);3. +4. |p_out|5. +6. |NULL|7. +8. /*未被定义,返回NULL*/9. +10. |p_out|11. +12. |2|13. +14.

10、15. mysql>SELECTp_out;16. +17. |p_out|18. +19. |2|20. +m.INOUT参数例子创建:1. mysql>DELIMITER/2. mysql>CREATEPROCEDUREdemo_inout_parameter(INOUTp_inoutint)3.->BEGIN4.5.->SELECTp_inout;->SETp_inout=2;6. ->SELECTp_inout;7. ->END;8. ->/9. mysql>DELIMITER;执行结果:1. mysql>SETp_in

11、out=1;2. mysql>CALLdemo_inout_parameter(p_inout);3. +4. |p_inout|5. +6. |1|7. +8.9. +10. |p_inout|11. +12. |2|13. +14.15. mysql>SELECTp_inout;16. +17. |p_inout|18. +19. |2|20. +(4).变量I.变量定义DECLAREvariable_name,variable_name.datatypeDEFAULTvalue;其中,datatype为MySQL的数据类型,如:int,float,date,varchar(l

12、ength)例如:1. DECLAREl_intintunsigneddefault4000000;2. DECLAREl_numericnumber(8,2)DEFAULT9.95;3. DECLAREl_datedateDEFAULT'1999-12-31'4. DECLAREl_datetimedatetimeDEFAULT'1999-12-3123:59:59'5. DECLAREl_varcharvarchar(255)DEFAULT'Thiswillnotbepadded'n.变量赋值SET变量名=表达式值,variable_name

13、=expression.田.用户变量i .在MySQL客户端使用用户变量1. mysql>SELECT'HelloWorld'intox;2. mysql>SELECTx;3. +4. |x|5. +6. |HelloWorld|7. +8. mysql>SETy='GoodbyeCruelWorld'9. mysql>SELECTy;10. +11. |y|12. +13. |GoodbyeCruelWorld|14. +15.16. mysql>SETz=1+2+3;17. mysql>SELECTz;18. +19. |

14、z|20. +21. |6|22. +ii .在存储过程中使用用户变量1. mysql>CREATEPROCEDUREGreetWorld()SELECTCONCAT(greeting,'World');2. mysql>SETgreeting='Hello'3. mysql>CALLGreetWorld();4. +5. |CONCAT(greeting,'World')|6. +7. |HelloWorld|8. +iii .在存储过程间传递全局范围的用户变量1. mysql>CREATEPROCEDUREp1()SE

15、Tlast_procedure='p1'2. mysql>CREATEPROCEDUREp2()SELECTCONCAT('Lastprocedurewas',last_proc);3. mysql>CALLp1();4. mysql>CALLp2();5. +6. |CONCAT('Lastprocedurewas',last_proc|7. +8. |Lastprocedurewasp1|9. +注意:用户变量名一般以开头滥用用户变量会导致程序难以理解及管理(5) .注释MySQL存储过程可使用两种风格的注释双模杠:-该风格

16、一般用于单行注释c风格:/*注释内容*/一般用于多行注释例如:1. mysql>DELIMITER/2. mysql>CREATEPROCEDUREproc1-name?储过程名3. ->(INparameter1INTEGER)/*parameters参数*/4. ->BEGIN/*startofblock语句块头*/5. ->DECLAREvariable1CHAR(10);/*variables变量声明*/6. ->IFparameter=17THEN/*startofIFIF条件开始*/7. ->SETvariable1='birds&

17、#39;/*assignment赋值*/8. ->ELSE9. ->SETvariable1='beasts'/*assignment赋值*/10. ->ENDIF;/*endofIFIF结束*/11.->INSERTINTOtablelVALUES(variablel);/*statementSQL语句*/12. ->END/*endofblock语句块结束*/13. ->/14. mysql>DELIMITER;4. MySQL存储过程的调用用call和你过程名以及一个括号,括号里面根据需要,加入参数,参数包括输入参数、输出参数、输

18、入输出参数。具体的调用方法可以参看上面的例子。5. MySQL存储过程的查询我们像知道一个数据库下面有那些表,我们一般采用showtables进行查看。那么我们要查看某个数据库下面的存储过程,是否也可以采用呢?答案是,我们可以查看某个数据库下面的存储过程,但是是令一钟方式。我们可以用cwheredb吸据库名';或者selectroutine_namefrominformation_schema.routineswhereroutine_schema=数据库名'一一或者showprocedurestatuswheredb数据库名

19、9;进行查询。如果我们想知道,某个存储过程的详细,那我们又该怎么做呢?是不是也可以像操作表一样用describe表名进行查看呢?答案是:我们可以查看存储过程的详细,但是需要用另一种方法:SHOWCREATEPROCEDURE数据库.存储过程名;就可以查看当前存储过程的详细。6. MySQL存储过程的修改ALTERPROCEDURE更改用CREATEPROCEDURE建立的预先指定的存储过程,其不会影响相关存储过程或存储功能。7. MySQL存储过程的删除删除一个存储过程比较简单,和删除表一样:DROPPROCEDURE从MySQL的表格中删除一个或多个存储过程8. MySQL存储过程的控制语句

20、(1) .变量作用域内部的变量在其作用域范围内享有更高的优先权,当执行到end。变量时,内部变量消失,此时已经在其作用域外,变量不再可见了,应为在存储过程外再也不能找到这个申明的变量,但是你可以通过out参数或者将其值指派给会话变量来保存其值。1. mysql>DELIMITER/2. mysql>CREATEPROCEDUREproc3()3. ->begin4. ->declarex1varchar(5)default'outer'5. ->begin6. ->declarex1varchar(5)default'inner

21、9;7. ->selectx1;8. ->end;9. ->selectx1;10. ->end;11. ->/12. mysql>DELIMITER;(2) .条件语句I.if-then-else语句1. mysql>DELIMITER/2. mysql>CREATEPROCEDUREproc2(INparameterint)3. ->begin4. ->declarevarint;5. ->setvar=parameter+1;6. ->ifvar=0then7. ->insertintotvalues(17);

22、8. ->endif;9. ->ifparameter=0then10. ->updatetsets1=s1+1;11. ->else12. ->updatetsets1=s1+2;13. ->endif;14. ->end;15. ->/16. mysql>DELIMITER;n.case语句:17. mysql>DELIMITER/18. mysql>CREATEPROCEDUREproc3(inparameterint)19. ->begin20. ->declarevarint;21. ->setvar

23、=parameter+1;22. ->casevar23. ->when0then24. ->insertintotvalues(17);25. ->when1then26. ->insertintotvalues(18);27. ->else28. ->insertintotvalues(19);29. ->endcase;30. ->end;31. ->/32. mysql>DELIMITER;(3) .循环语句I.while-endwhile:1. mysql>DELIMITER/2. mysql>CREATE

24、PROCEDUREproc4()3. ->begin4. ->declarevarint;5. ->setvar=0;6. ->whilevar<6do7. ->insertintotvalues(var);8. ->setvar=var+1;9. ->endwhile;10. ->end;11. ->/12. mysql>DELIMITER;n.repeat-endrepeat:它在执行操作后检查结果,而while则是执行前进行检查。1. mysql>DELIMITER/2. mysql>CREATEPROCEDU

25、REproc5()3. ->begin4. ->declarevint;5. ->setv=0;6. ->repeat7. ->insertintotvalues(v);8. ->setv=v+1;9. ->untilv>=510. ->endrepeat;11. ->end;12. ->/13. mysql>DELIMITER;m.loopendloop:repeat循环一loop循环不需要初始条件,这点和while循环相似,同时和样不需要结束条件,leave语句的意义是离开循环。1. mysql>DELIMITE

26、R/2. mysql>CREATEPROCEDUREproc6()3. ->begin4. ->declarevint;5. ->setv=0;6. ->LOOP_LABLE:100P7. ->insertintotvalues(v);8. ->setv=v+1;9. ->ifv>=5then10. ->leaveLOOP_LABLE;11. ->endif;12. ->endloop;13. ->end;14. ->/15. mysql>DELIMITER;IV.LABLES标号:标号可以用在begin

27、repeatwhile或者loop语句前,语句标号只能在合法的语句前面使用。可以跳出循环,使运行指令达到复合语句的最后一步。(4) .ITERATE迭代I.ITERATE:通过引用复合语句的标号,来从新开始复合语句1. mysql>DELIMITER/2. mysql>CREATEPROCEDUREproc10()3. ->begin4. ->declarevint;5. ->setv=0;6. ->LOOP_LABLE:100P7. ->ifv=3then8. ->setv=v+1;9. ->ITERATELOOP_LABLE;10. -

28、>endif;11. ->insertintotvalues(v);12. ->setv=v+1;13. ->ifv>=5then14. ->leaveLOOP_LABLE;15. ->endif;16. ->endloop;17. ->end;18. ->/19. mysql>DELIMITER;9. MySQL存储过程的基本函数(1) .字符串类CHARSET(str)/返回字用字符集CONCAT(string2,.)/连接字用INSTR(string,substring)/返回substring首次在string中出现的位

29、置,不存在返回0LCASE(string2)转换成小写LEFT(string2,length)/从string2中的左边起取length个字符LENGTH(string)/string长度LOAD_FILE(file_name)/从文件读取内容LOCATE(substring,string,start_position)同INSTR,但可指定开始位置LPAD(string2,length,pad)/重复用pad加在string开头,直到字用长度为lengthLTRIM(string2)/去除前端空格REPEAT(string2,count)/重复count次REPLACE(str,search

30、_str,replace_str)/£str中用replace_str替换search_strRPAD(string2,length,pad)/ftstr后用pad补充,直到长度为lengthRTRIM(string2)/去除后端空格STRCMP(string1,string2)逐字符比较两字串大小,SUBSTRING(str,position,length)/从str的position开始,取length个字符,注:mysql中处理字符串时,默认第一个字符下标为1,即参数position必须大于等于11. mysql>selectsubstring('abcd'

31、;,0,2);2. +3. |substring('abcd',0,2)|4. +5. II6. +7. 1rowinset(0.00sec)8.9. mysql>selectsubstring('abcd',1,2);10. +11. |substring('abcd',1,2)|12. +13. |ab|14. +15. 1rowinset(0.02sec)TRIM(BOTH|LEADING|TRAILINGpaddingFROMstring2)/去除指定位置的指定字符UCASE(string2)转换成大写RIGHT(string2,l

32、ength)/取string2最后length个字符SPACE(count)/生成count个空格.数学类ABS(number2)绝对值BIN(decimal_number)十进制转二进制CEILING(number2)/向上取整CONV(number2,from_base,to_base)删制转换FLOOR(number2)/向下取整FORMAT(number,decimal_places)淋留小数位数HEX(DecimalNumber)转十六进制注:HEX()中可传入字符串,则返回其ASC-11码,如HEX('DEF')返回4142143也可以传入十进制整数,返回其十六进制

33、编码,如HEX(25)返回19LEAST(number,number2,.)求最小值MOD(numerator.denominator)/冰余POWER(number.power)/冰指数RAND(seed)随机数ROUND(number.decimals)四舍五入,decimals为小数位数注:返回类型并非均为整数,如:(1)默认变为整形值1. mysql>selectround(1.23);2. +3. |round(1.23)|4. +5. |1|6. +7. 1rowinset(0.00sec)8.9. mysql>selectround(1.56);10. +11. |r

34、ound(1.56)|12. +13. |2|14. +15. 1rowinset(0.00sec)(2)可以设定小数位数,返回浮点型数据1. mysql>selectround(1.567,2);2. +3. |round(1.567,2)|4. +5. |1.57|6. +7. 1rowinset(0.00sec)SIGN(number2)/(3).日期时间类ADDTIME(date2,time_interval)/将time_interval力口至Udate2CONVERT_TZ(datetime2,fromTZ,toTZ)/转换时区CURRENT_DATE()/当前日期CURRE

35、NT_TIME()/当前时间CURRENT_TIMESTAMP()/当前时间戳DATE(datetime)返回datetime的日期部分DATE_ADD(date2,INTERVALd_valued_type)/在date2中加上日期或时间DATE_FORMAT(datetime,FormatCodes)使用formatcodes格式显示datetimeDATE_SUB(date2,INTERVALd_valued_type)/在date2上减去一个时间DATEDIFF(date1,date2)/两个日期差DAY(date)返回日期的天DAYNAME(date)/英文星期DAYOFWEEK(d

36、ate)/星期(1-7),1为星期天DAYOFYEAR(date)/一年中的第几天EXTRACT(interval_nameFROMdate)/从date中提取日期的指定部分MAKEDATE(year,day)/给出年及年中的第几天,生成日期串MAKETIME(hour,minute,second)/生成时间串MONTHNAME(date)/英文月份名NOW()/当前时间SEC_TO_TIME(seconds)/秒数转成时间STR_TO_DATE(string,format)/字串转成时间,以format格式显示TIMEDIFF(datetime1,datetime2)/两个时间差TIME_TO_SEC(time)/时间转秒数WEEK(date_time,start_of_week)/第几周YEAR(datetime)/年份DAYOFMONTH

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论