源无极

导航

 

 

一、创建存储函数

与存储过程类似功能是存储函数。语法如下


CREATE  FUNCTION  func_name( func_parameter])

RETURNS type
[characteristic...]  routine_body

 

CREATE  FUNCTION  :是用来创建存储函数的关键字,

func_name:存储函数名称

func_parameter指定存储函数的参数列表,列表如下

[ IN | OUT | INOUT ]  param_name  type

其中,IN是输入参数,out是输出参数 ,INOUT是即可输入也可输出,param_name  是参数名称,type是参数类型。

 

案例一、创建存储函数,名称为name_student, 该函数返回查询到的结果,数值类型为字符串型

 

 

二、调用存储函数

函数的调用和MYSQL内部函数的调用性质一样。

修改一下,因为函数定义返回的值是一个

 

 

 

 

 三、查看存储函数

语法一、

SHOW FUNCTION STATUS LIKE 'N%'

SHOW FUNCTION STATUS 是查看所有创建的函数

查看某一个函数

 

 

语法二

SHOW CREATE FUNCTION sp_name

 

 

 

语法三

SELECT  *  from information_schema.ROUTINES
WHERE ROUTINE_NAME='sp_name';

 

 

 

 

 

 

 

 三、删除存储函数

DROP FUNCTION [ IF EXISTS ] sp_name

 

 

 

查看

 

 

 

四、深入学习自定义函数

1.变量

在存储过程和函数中都可以使用变量,变量的定义使用DECLARE ,定义之后可以为变量赋值,

变量的作用域为 BEGIN...END

定义:

DECLARE var_name[ ... , ] type [ DEFAULT value ]

DECLARE :声明变量

var_name:变量名称

type :变量类型

DEFAULT value :为变量提供一个默认值,默认值可以是常数也可以是表达式,

如果没有给变量指定默认值,则为null

 

案例一   定义名称为studentid 的变量,类型为char 默认值为 ‘ 一年级’

DECLARE  studentid   char(10)  default '一年级'

 

变量赋值

在mysql中使用set语句为变量赋值

SET  var_name =expr [ , var_name=expr ]...

SET  :给变量赋值

var_name 变量名称

expr :表达式

案例二

 声明三个变量,v1,v2,v3 ,其中v1,v2数据类型为INT,v3的数据类型为char

DECLARE v1,v2 int;
DECLARE v3 char(30);
SET v1=66,v2=88,v3='自定义变量'

在mysql中还可以使用SELECT ... INTO 语句为变量赋值,语法如下

SELECT col_name [,...]  INTO  var_name[,...]
FROM table_name WHERE condition

col_name :是查询到的列字段名

var_name:变量的名称

 

案例三

声明变量student_name ,将编号为2的学生姓名赋值给该变量

 

 

2.流程控制语句

在存储过程和函数中使用流程控制来控制语句与的执行,mysql中用来构造控制流程的语句有

if ,case ,loop. leave ,iterate ,repeat ,where 语句

 

1)IF语句用来进行判断,根据结果的true和false执行不同的语句。语法

IF search_condition THEN statement_list
[ ELSEIF search_condition THEN statement_list ]...
[ ELSE statement_list ]
END IF

 search_condition :为true 则执行响应的SQL ,如果为false执行ELSE子句中的语句

statement_list:表示不同条件的执行语句,可以包含一条或是多条。

例子:

 

 

 如果价格大于等于30,输出字符串:'价格太高',否则输出‘价格适中’

 

2)CASE语句可以实现比IF更加复杂的条件判断,有两种基本格式,第一种如下

CASE  case_value
WHEN when_value THEN statement_list
[ WHEN when_value THEN statement_list ]...
[ELSE statement_list]
END CASE

case_value :是条件判断的表达式,该表达式的值决定哪个when子句被执行。

when_value :表达式可能的值,如果case_value 和哪个when_value 值相同,执行对应的THEN

关键字后的statement_list 

case第二种格式

CASE
WHEN  search_condition  THEN  statement_list
[ WHEN search_condition THEN statement_list ]...
[ ELSE statement_list ]
END CASE

案例

 

 

 或是下面的写法

 

 

 

3)LOOP语句:可以重复执行特定的语句,实现简单循环,但是LOOP本身并不会进行判断

没有停止循环的语句,必须使用LEAVE语句才能停止循环,跳出循环过程。语法如下

[ begin_label: ] LOOP

statement_list 

END LOOP [ end_label ]

begin_label和end_label 表示循环开始和结束的标志,可以省略;

statement_list :需要循环执行的语句。

例子

 

 

没有跳出循环,该循环为死循环

 

4)LEAVE语句 :跳出任何被标注的流程控制语句,语法:

LEAVE label

label:表示循环的标志  。 leave和循环或是BEGIN....END一起使用。

 

例子:跳出循环的语句

 

5)ITERATE语句:也是用来跳出循环的,但是它只能出现在LOOP ,REPEAT和WHERE 语句内

ITERATE是跳出本次循环,然后直接进入下一次循环,

ITERATE:再次循环  。语法

ITERATE label

例子

 

 

输入参数a,当a小于10,使用ITERATE跳出本次循环,有一次从头开始LOOP循环,a的值在加1

当a大于10,执行下面LEAVE跳出整个循环。

 

6)REPEAT语句:创建的是带条件判断的循环语句,循环语句每次执行完都会对表达式进行判断

若是表达式为真,则结束循环,否则再次循环。语法

[begin_label:] REPEAT
statement_list
UNTIL search_condition
END REPEAT [end_label]

search_condition:是结束循环的条件,条件为真跳出循环,否则再次执行循环。

 

 当ss小于100时再次循环ss+1的操作

7WHILE  语句 :也是有条件控制的循环语句,和REPEAT不同,在执行时,先对条件表达式进行判断,若为true,则执行

循环内的语句,否则退出整个循环。

[begin_label:]  WHILE  search_condition DO
statement_list
END WHILE [end_label]

例子

 

 如果ss小于100,则循环ss+1的操作,否则退出循环。

 

3.光标的使用

在存储过程和自定义函数中的查询可能会返回多条记录,可以使用光标来逐条读取查询结果集中的记录

光标在很多其他地方书籍被称为游标,光标的使用包括:光标的声明、打开光标、使用光标、关闭光标。

注意:光标必须在处理程序之前声明,在变量和条件之后声明

1)声明光标

使用DECLARE声明,语法如下

DECLARE  cursor_name   CURSOR   FOR  select_statement

cursor_name   :光标名称

select_statement:查询语句,返回一个结果集,声明的光标基于这个结果集进行操作用户可以定义多个光标,但是一个块中的每一个

光标必须有唯一的名称

 

例子1

声明一个光标名称为cursor_student

SQL语句如下

 

 

 2)打开光标

OPEN   cursor_name 

例子

 

 

3)使用光标

FETCH   cursor_name   INTO   var_name [, var_name]...

cursor_name   :先前声明的光标

 var_name :将光标声明中的select 语句中的查询信息存储在该参数中,var_name 必须在光标声明前定义好

FETCH:取

例子:使用光标名称为cursor_student,将查询到的数据存储 在变量e_no、e_name中。

sql

 

 

4)关闭光标

CLOSE   cursor_name 

例子

 

 4.定义条件和处理程序

 通过定义条件和处理程序可以解决,在存储过程和自定义函数运行出现错误还可以继续运行。

 1.定义条件:

DECLARE   condition_name   CONDITION   FOR   condition_value

condition_value:

SQLSTATE  [VALUE]   sqlstate_value  |  mysql_error_code

语法中

condition_name   :条件的名称,

condition_value:条件的类型

sqlstate_value和mysql_error_code都可以表示MYSQL的错误,sqlstate_value是长度为5的字符串类型的代码

mysql_error_code是表示数值类型的错误代码

 

例子 :定义ERROR 110 (44000)的错误,名称为command_not_find

方法一:

 

 方法二:

 

  1.定义处理程序:

 

语法

DECLARE  handler_type  HANDLER   FOR    condition_value[,...]   sp_statement

参数说明:

handler_type  :CONTINUE  |  EXIT | UNDO

handler_type  :是错误处理方式,取以上三个值的一个

CONTINUE  :遇到错误不处理

exit:遇到错误退出

UNDO:遇到错误撤销之前的操作

condition_value:
SQLSTATE  [VALUE]  sqlstate_value
condition_name
SQLWARNING
NOT FOUND_
SQLEXCEPTION
mysql_error_code

 

说明:

condition_value表示错误的类型,该参数可以取以下值

SQLSTATE  [VALUE]  sqlstate_value字符串错误值

condition_name:使用DECLARE   CONDITION定义的错条件名称。

SQLWARNING:NOT FOUND匹配所有以02开头的SQLSTATE错误代码,SQLEXCEPTION匹配所有

没有被SQLWARNING或是NOT FOUND捕获的错误代码

 

定义处理程序的几种方法

方法一

 

 

 

 

 该方法定义捕获sqlstate_value 值,如果遇到sqlstate_value 为23S00,执行CONTINUE操作,并且给变量x赋值20.

方法二

 

 该方法定义捕获mysql_error_code值,如果遇到mysql_error_code为1146,执行CONTINUE操作,并且给变量x赋值20.

 

方法三

 

该方法先定义NO_TABLE条件,遇到1150错误,执行CONTINUE操作,并输出信息 ‘ NO_TABLE’

 

 方法四

 

 SQLWARNING捕获所有以01开头的sqlstate_value 值,然后执行EXIT操作,并输出ERROR

 方法五

 

  not  found 捕获所有以02开头的sqlstate_value 值,然后执行EXIT操作,并输出ERROR

 方法六

 

SQLEXCEPTION 捕获所有没有被SQLWARNING或是NOT FOUND捕获的sqlstate_value 值,然后执行EXIT操作,并输出ERROR

 

总结:

1.存储过程的好处?

优点:

       效率高:存储过程在创建时已经对其进行了语法分析和优化工作,一旦执行,在内存中会保留该存储过程

当数据库服务器再次调用该存储过程时可以直接内存进行读取

       降低网络通信量:使用存储过程可以实现客户机只需要通过网络向服务器发出存储过程的名字和参数

就可以执行许多条SQL语句,当存储过程包含上白行SQL语句时,该执行性能尤为明显。

      业务逻辑可以封装在存储过程中,方便实施企业规则:利用存储过程将企业规则的运算程序存储在数据库服务器中,

由RDBMS统一管理,当用户的规则发生变化时,可以只是修改存储过程,无需修改其应该程序,

这样不仅容易维护,且简化了复杂的操作。

  

2.存储过程参数可以使用中文吗?

可以,在定义存储过程的时候在后面加上character set gbk ,否则调用存储过程会出错,比如定义userInfo,sql如下

 

 

3.在存储过程中定义的局部变量和会话变量相同吗?

不同,会话变量前必须加@,且会话变量的作用域是整个会话;存储过程体可以使用DECLARE语句定义局部变量

存储过程的参数也是局部变量,对于局部变量的使用不能再前面加@符号

 

posted on 2019-10-08 20:45  源无极  阅读(559)  评论(0编辑  收藏  举报