好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Mysql性能调优(三)

procedure procedure_name ( [ proc_parameter [ , . . . ] ] ) begin --SQL语句 end ;

??我们通过一个案例来具体说明存储过程的创建。方便大家更好的理解存储过程的语法。

  delimiter  $
 create   procedure  pro_test1 (  ) 
 begin 
	 select   ‘hello mysql‘  ; 
 end  $
 delimiter   ; 
 

??这里需要我们注意的是:我们在案例中用到了一个关键字——“delimiter”,该关键字 用来声明sql语句的分隔符 。这个关键字其实就是告知mysql解释器,该命令是否已经结束了,mysql是否可执行了。 一般在默认情况下 :delimiter是;。在命令行客户端中,如果有一行命令以分号结束,那么回车后,mysql将会执行该命令。

3、调用存储过程

??我们创建好存储过程之后,可以再mysql中调用存储过程,调用语法如下:

  call  procedure_name (  ) 
 

4、查看存储过程

??我们在调用存储过程之后,就可以在MySQL中查看存储过程。以下就是存储查看语句的如下:

  --首先我们查询db_name数据库中的所有的存储过程; 
 select  name  from  mysql .  proc   where  db  =   ‘db_name‘  ; 
 --查询存储过程的状态信息 
 show   procedure   status  ; 
 --查询某个存储过程的定义 
 show   create   procedure  test . pro_test1 G ; 
 

5、删除存储过程

??存储过程与其他的mysql语句一样,可以创建,可以查看,当然也可以删除,接下来,我们介绍mysql中存储过程的删除,删除的语法如下:

  drop   procedure   [  if   exists  ]  sp_name ; 
 

6、语法

??通过前面的介绍,相信大家对存储过程有一定的了解,其实,我们学过编程的可以知道,存储过程也是可以编程的,这就意味着我们可以同样地在创建存储的过程也可以使用我们常见的 变量、表达式以及控制结构 ,可以完成比较复杂的功能。

(1)、变量 declare
??我们首先给大家介绍存储过程中的变量,变量的声明用 declare 关键字。我们可以通过declare可以定义一个局部变量,但是该变量的 作用范围 只能在begin…end块中。主要的语法如下:
  declare  var_name [  ,  .  .  .  ]   type   [  default   value  ] 
 

??我们介绍了declare的语法,我们通过一个案例来说明declare的用法。

  delimiter  $
 create   procedure  pro_test2 (  ) 
 begin 
	 declare  num  int   default   5  ; 
	 select  num +   10  ; 
 end $
 delimiter   ; 
 
set
??我们前面介绍了declare定义一个局部变量,接下来,我们介绍set直接赋值,可以赋常量或者赋表达式,具体的语法如下:
  set  var_name  =  expr  [  ,  var_name  =  expr ]  .  .  . 
 

??我们介绍了set的语法,我们通过一个案例来说明set的用法。

  delimiter  $
 create   procedure  pro_test3 (  ) 
 begin 
	 declare  name  varchar  (  20  )  ; 
	 set  name  =   ‘mysql‘  ; 
	 select  name ; 
 end $
 delimiter   ; 
 

??当然,我们可以通过select…into方法进行赋值操作,接下来,我们可以通过一个案例来说明用法:

  delimiter  $
 create   procedure  pro_test5 (  ) 
 begin 
	 declare  countnum  int  ; 
	 select   count  (  *  )   into  countnum  from  city ; 
	 select  countnum ; 
 end $
 delimiter   ; 
 
(2)、if条件判断

??前面主要介绍了存储过程中的变量,主要包括定义一个变量declare以及赋值关键字set。接下来,给大家介绍if条件的判断语句。语法结构如下:

  if  search_condition  then  statement_list
	 [  elseif  search_condition  then  statement_list ] 
	 [  else  statement_list ] 
 end   if 
 

??接下来我们通过一个案例来呈现if条件判断语句的实现,为了方便大家理解,具体的案例如下:

?? 根据定义的身高变量,判定当前身高的所属的身材类型。

180及以上 ——————> 身材高挑 170-180 ——————> 标准身材 170以上 ——————> 一般身材

??具体存储过程如下:

  create   procedure  pro_test4 (  ) 
 begin 
	 declare  height  int   default   175  ; 
	 declare  description  varchar  (  50  )   default   ‘‘  ; 
	 if  height  >=   180   then   set  description  =   ‘身材高挑‘  ; 
	 elseif  height  >=   170   and  height  <   180   then   set  description  =   ‘标准身材‘  ; 
	 else   set  description  =   ‘一般身材‘  ; 
 end   if  ; 
 select  concat (  ‘身高‘  ,  height ,   ‘对应的身材类型为:‘  , description )  ; 
 end  $ ; 
 

??我们可以通过调用语句来实现存储过程,具体实现如下:

  call  pro_test6 (  )  ; 
 

??具体的结果如下:

(3)、传递参数

??前面我们也提到过,存储过程也可以编程,也有函数的,我们学过编程语言的,无论是java也好还是c语言也罢,其中函数均可以传参数的。具体语法的格式如下:

  create   procedure  procedure_name (  [  in  /  out  /  inout  ] 参数名 参数类型 ) 
 

??根据我们刚才介绍的传递参数的语法中,有in、out以及inout,因此,我们接下来给大家介绍他们三者的含义:

in :该参数可以作为输入,也就是需要调用方传入值,这里我们如果不特殊指定就是默认值。 out :该参数作为输出,也就是该参数可以作为返回值 inout :既可以作为输入参数,也可以作为输出参数

??还是之前我们提到的身高问题来分别为大家实现in、out与inout的使用方法,由于前面的我们提到的身材类型,因此,就不在重新描述。
??首先,让我们用in来实现身高问题,具体的实现语句如下:

  create   procedure  pro_test5 (  in  height  int  ) 
 begin 
	 declare  description  varchar  (  50  )   default   ‘‘  ; 
	 if  height  >=   180   then   set  description  =   ‘身材高挑‘  ; 
	 elseif  height  >=   170   and  height  <   180   then   set  description  =   ‘标准身材‘  ; 
	 else   set  description  =   ‘一般身材‘  ; 
 end   if  ; 
 select  concat (  ‘身高‘  ,  height ,   ‘对应的身材类型为:‘  , description )  ; 
 end  $ ; 
 

??接下来让我们out输出实现身高问题

  create   procedure  pro_test5 (  in  height  int  ,   out  description  varchar  (  100  )  ) 
 begin 
	 declare  description  varchar  (  50  )   default   ‘‘  ; 
	 if  height  >=   180   then   set  description  =   ‘身材高挑‘  ; 
	 elseif  height  >=   170   and  height  <   180   then   set  description  =   ‘标准身材‘  ; 
	 else   set  description  =   ‘一般身材‘  ; 
 end   if  ; 
 end  $ ; 
 

??接下来,我们调用这个函数

  call  pro_test5 (  168  ,   @description  ) $
 select   @description$ 
 

??这里需要我们注意的是在调用中出现了一个@description的关键字。接下来给大家介绍相关的知识:

?? @description:这种变量要在变量名称前面加“@”符号,这种符号叫做用户会话变量,代表整个会话过程他都是有作用的,这个类似于全局变量一样。 ??@@global.sort_buffer_size:这种在变量前加上“@@”符号,叫做系统变量。 (4)、case结构

??前面介绍了if条件判断,接下来我们介绍case结构判断。具体的语法结构如下:

  --**方法一**: 
 case  case_value
	 when  when_value  then  statement_list
	 [  when  when_value  then  statement_list ]  .  .  . 
	 [  else  statement_list ] 
 end   case  ; 
 --方法二: 
 case 
	 when  search_condition  then  statement_list
	 [  when  search_condition  then  statement_list ]  .  .  . 
	 [  else  statement_list ] 
 end   case 
 

??以上是case的基本语法,接下来我们通过一个案例来说明case的用法;具体的案例如下:

??给定一个月份,然后计算出所在的季度

  create   procedure  pro_test7 ( mon  int  ) 
 begin 
	 declare  result  varchar  (  10  )  ; 
	 case 
		 when  mon  >=  1   and  mon  <=   3   then 
			 set  result  =   ‘第一季度‘  ; 
		 when  mon  >=  4   and  mon  <=   6   then 
			 set  result  =   ‘第二季度‘  ; 
		 when  mon  >=  7   and  mon  <=   9   then 
			 set  result  =   ‘第三季度‘  ; 
		 else  
			 set  result  =   ‘第四季度‘  ; 
	 end   case  ; 
	 select  concat (  ‘传递的月份为:‘  ,  mon ,   ‘,计算出的结果为:‘  ,  result )   as  content ; 
 end $
 
(5)、while循环

??前面介绍了条件格式;其中包括我们常见的if语句和case语句。接下来,给大家介绍循环语句,其中主要包括while、repeat和loop函数。首先给大家介绍while循环,具体语法如下:

  while  search_condition  do 
	statement_list
 end   while  ; 
 

??接下来我们通过一个案例来说明case的用法;具体的案例如下:

??计算从1加到n的值 --累加

??具体的实现如下:

  create   procedure  pro_test8 ( n  int  ) 
 begin 
	 declare  total  int   default   0  ; 
	 declare  num  int   default   1  ; 
	 while  num  <=  n  do  
		 set  total  =  total  +  num ; 
		 set  num  =  num  +   1  ; 
	 end   while  ; 
	 select  total ; 
 end $
 
(6)、repeat结构

??我们刚才为大家介绍了while循环,接下来给大家介绍repeat结构。repeat结构是有条件的循环控制语句,当满足条件的时候退出循环。接下里给大家介绍repeat与while两种循环的结构的区别:

while是满足条件才执行的 repeat是满足条件就退出循环

??具体的语法如下:

  repeat  
	statement_lsit
	until search_condition
 end   repeat  ; 
 

??接下来我们通过一个案例来说明repeat的用法;这个案例和前面的案例是一个样的,因此实现如下:

  create   procedure  pro_test9 ( n  int  ) 
 begin 
	 declare  total  int   default   0  ; 
	 repeat 
		 set  total  =  total  +  n ; 
		 set  n  =  n  -   1  ; 
		until n  =   0 
	 end   repeat  ; 
	 select  total ; 
 end $
 
(7)、loop语句

??我们介绍最后一种循环语句loop函数,loop可以实现简单的循环,退出循环的条件使用其他语句的定义,通常可以使用leave语句实现,具体的语法实现如下:

  [ begin_label: ]   LOOP 
	statement_list
 end   loop  [ end_label ] 
 

??这里需要我们注意的是: 如果不在statement_list中增加退出循环的语句,那么loop语句可以用来实现简单的死循环。

(8)、leave语句

??我们刚才介绍了loop循环语句,也提到了loop循环结构要与leave语句搭配使用,其中的 leave语句是用来退出loop中的循环的 。一般情况,要和begin…end或者循环一起使用。接下来我们用loop和leave的简单例子,具体实现如下:

  create   procedure  pro_test10 ( n  int  ) 
 begin 
	 declare  total  int   default   0  ; 
	c: loop 
		 set  total  =  total  +  n ; 
		 set  n  =  n  -   1  ; 
		 if  n  <=   0   then 
			 leave  c ; 
		 end   if  ; 
	 end   loop  c ; 
	 select  total ; 
 end $
 
(9)、游标/光标

??我们前面介绍了三种循环结构,下来给大家介绍一种特别重要的数据类型:游标。游标是用来存储查询结果集的数据类型,在存储过程和函数中可以使用光标对结果进行循环处理。光标的使用包括光标的声明、open、fetch和close,其中的语法如下:

  --声明光标: 
 declare  cursor_name  cursor   for  select_statement ; 
 --open光标 
 open  cursor_name ; 
 --fetch光标 
 fetch  cursor_name  into  var_name  [  ,  var_name ]  .  .  . 
 --close光标 
 close  cursor_name ; 
 

??介绍完游标的基本语法的时候,接下来,我们通过一个案例来具体实现游标的应用。首先我们初始化的脚本,即首先创建一张表,并且插入一些数据。

  create   table  emp ( 
	id  int  (  11  )   not   null   auto_increment  , 
	name  varchar  (  50  )   not   null   comment   ‘姓名‘  , 
	age  int  (  11  )   comment   ‘年龄‘  , 
	salary  int  (  11  )   comment   ‘薪水‘  , 
	 primary   key  (  ` id `  ) 
 )  engine  =  innodb   default   charset  = utf8 ; 
 insert   into  emp ( id ,  name ,  age ,  salary )   values   (  null  ,   ‘stefan‘  ,   16  ,   28000  )  ,  (  null  ,   ‘napoleon‘  ,   26  ,   18000  )  ,  (  null  ,   ‘porrty‘  ,   18  ,   8000  )  ,  (  null  ,   ‘张三‘  ,   26  ,   2600  )  ; 
 

??建立好表也插入了数据,接着我们可以查看emp表中的数据,并逐行获取进行展示。

  create   procedure  pro_test11 (  ) 
 begin 
	 declare  e_id  int  (  11  )  ; 
	 declare  e_name  varchar  (  50  )  ; 
	 declare  e_age  int  (  11  )  ; 
	 declare  e_salary  int  (  11  )  , 
	 declare  emp_result  cursor   for   select   *   from  emp ; 
	 declare   exit   handler   for   not  found  set  has_data =  0  ; 
	 open  emp_result ; 
	 repeat  
		 fetch  emp_result  into  e_id ,  e_name ,  e_age ,  e_salary ; 
		 select  concat (  ‘id=‘  ,  e_id ,   ‘,name=‘  , e_name ,   ‘, age=‘  ,  e_age ,   ‘,薪资为:‘  ,  e_salary )  ; 
		until has_data  =   0 
	 end   repeat  ; 
	 close  emp_result ; 
 end $
 

??我们的存储过程已经全部介绍完了,存储过程比较重要,也是一个很高级的写法,能够希望大家很好的掌握,接下来,给大家介绍存储函数。

二、存储函数

??前面介绍了存储过程,接下来我们介绍存储函数的语法结构:

  create   function  function_name (  [ param  type   .  .  .  ]  ) 
 returns   type 
 begin 
	 .  .  . 
 end  ; 
 

??我们接下来定义一个存储函数,获取满足条件(city)的总记录数。接下来实现如下:

  delimiter  $
 create   function  count_city ( countryId  int  ) 
 returns   int 
 begin 
	 declare  cnum  int  ; 
	 select   count  (  *  )   into  cnum  from  city  where  country_id  =  countryId ; 
	 return  cnum ; 
 end $
 delimiter   ; 
 

??接下来,我们调用该存储函数,具体实现如下:

  select  count_city (  1  )  ; 
 select  count_city (  2  )  ; 
 

??由于存储函数比较简单,因此,我们在介绍的时候比较简单。

总结

??我们最近的文章均会给大家介绍mysql的性能,前两篇文章我们分别介绍了索引的相关知识以及视图以及触发器,本文给大家介绍了存储过程与存储函数的相关内容。存储过程的介绍主要包括:基本概念、创建、调用、删除存储过程,另外还介绍了在mysql中变量的申明以及赋值、应用,另外还给大家介绍mysql中存储过程中的三种循环结构。其次给大家介绍游标的相关内容。最后,我们介绍了存储函数的语法。因此,mysql是很重要的一个技能,几乎计算机中的每个岗位都需要一个mysq技能,因此,需要我们特别的掌握。生命不息,奋斗不止,我们每天努力,好好学习,不断提高自己的能力,相信自己一定会学有所获。加油!!!

转:

Mysql性能调优(三)

Mysql性能调优(三)

标签:HERE   插入   tap   case语句   --   list   keyword   删除   from   

查看更多关于Mysql性能调优(三)的详细内容...

  阅读:31次