当前位置:   article > 正文

sql之自定义函数(4)_sql自定义函数

sql自定义函数

知识点:

  1. 自定义函数定义
  2. 创建、调用、删除自定义函数
  3. 自定义函数的应用
  4. 深入自定义函数
    1. 复合结构
    2. 局部变量的创建、赋值;全局变量的创建
    3. 流程控制语句:条件语句(if、case)、控制循序条件语句(leave跳出循环、iterate跳出当前循环)、循环语句(loop、repeat、while)
       

一.定义

用户自定义函数(user-defined function,UDF)是一种对MySQL扩展的途经,其用法与内置函数相同。 

 

二.创建、修改、删除自定义函数

1.创建自定义函数:无参自定义函数、有参自定义函数

  1. 创建UDF:
  2.   CREATE [AGGREGATE] FUNCTION function_name(parameter_name type,[parameter_name type,...])
  3.   RETURNS {STRING|INTEGER|REAL}
  4.   runtime_body
  5. 简单来说就是:
  6.   CREATE FUNCTION 函数名称(参数列表)
  7.   RETURNS 返回值类型
  8.   函数体
  9. 解析:
  10. returns后面的为返回值类型,return后面的为返回值。

自定义函数有两个必要条件: 

  1. 参数 
  2. 返回值:return后面的为返回值

函数可以返回任意类型的值,同样可以接收这些类型的参数。
函数的参数和返回值之间没有必然的内在的联系。

关于函数体

  • 函数体由合法的sql语句构成;
  • 函数体可以是简单的SELECT或INSERT语句;
  • 函数体如果为复合结构(多个语句要执行)则使用BEGIN…END语句;
  • 复合结构可以包含声明,循环,控制结构; 

注意:

1.如果在创建函数的时候遇到you *might* want to use the less safe log_bin_trust_function_creators variable

需要执行 :SET GLOBAL log_bin_trust_function_creators = 1; 

2.在输入要执行的sql语句后,后面的分号为当前默认的分隔符,导致函数无法再继续输入。因此需要修改默认的分隔符。

需要执行:delimiter

#修改默认的结束符";"为"
",以后的SQL语句都要以"$$"作为结尾

 

例1:创建无参自定义函数:返回当前时间的,年月日 时分秒。

  1. 第一种:
  2. delimiter$$ #将默认的结束符";"修改为"$$"
  3. create function f1()
  4. returns datetime
  5. begin
  6. return now();
  7. end$$
  8. delimiter; #改回;
  9. 第二种:
  10. delimiter$$
  11. create function f1()
  12. returns datetime
  13. return now()$$
  14. delimiter;

例2:创建有参自定义函数:求两个数的平均值。

  1. DELIMITER$$
  2. CREATE FUNCTION f2(num1 SMALLINT UNSIGNED, num2 SMALLINT UNSIGNED)
  3. RETURNS FLOAT(10,2) UNSIGNED
  4. RETURN (num1+num2)/2$$
  5. DELIMITER;

例3:创建具有复合结构函数体的自定义函数:创建一个函数向表中插入数据,并返回所插入数据的id。

  1. DELIMITER$$
  2. CREATE FUNCTION f4()
  3. RETURNS INT(10) UNSIGNED
  4. BEGIN
  5. INSERT INTO goods(goods_name,goods_num) VALUES('圆珠笔',10);
  6. RETURN LAST_INSERT_ID();
  7. END$$
  8. DELIMITER;

2.调用自定义函数语法:(和使用内置函数一样,使用它)

SELECT function_name(parameter_value,...);

3.删除自定义函数语法:

drop function [IF EXISTS] function_name;

三.自定义函数的应用

四.深入使用自定义函数

1.复合结构

参考例3

2.局部变量和全局变量

自定义函数中定义局部变量语法:

  1. DECLARE var_name[,varname]...date_type [DEFAULT VALUE];
  2. 简单来说就是:
  3. DECLARE 变量1[,变量2,... ]变量类型 [DEFAULT 默认值];

这些变量的作用范围是在BEGIN...END程序中,而且定义局部变量语句必须在BEGIN...END的第一行定义

示例:

 

  1. DELIMITER $$
  2. CREATE FUNCTION addTwoNumber(x SMALLINT UNSIGNED, Y SMALLINT UNSIGNED)
  3. RETURNS SMALLINT
  4. BEGIN
  5. DECLARE a, b SMALLINT UNSIGNED DEFAULT 10;
  6. SET a = x, b = y;
  7. RETURN a+b;
  8. END$$

 

上边的代码只是把两个数相加,当然,没有必要这么写,只是说明局部变量的用法,还是要说明下:这些局部变量的作用范围是在BEGIN...END程序中

变量赋值语法:

  1. SET parameter_name = value[,parameter_name = value...]
  2. SELECT INTO parameter_name
  3. 例: 
  4. ...在某个UDF中...
  5. DECLARE x int;
  6. SELECT COUNT(id) FROM tdb_name INTO x;
  7. RETURN x;
  8. END$$

用户变量定义语法:(可以理解成全局变量)

  1. SET @param_name = value
  2. 例:
  3. SET @allParam = 100;
  4. SELECT @allParam;

上述定义并显示@allParam用户变量,其作用域只为当前用户的客户端有效

3.自定义函数中流程控制语句语法:

存储过程和函数中可以使用流程控制来控制语句的执行。

MySQL中可以使用IF语句、CASE语句、LOOP语句、LEAVE语句、ITERATE语句、REPEAT语句和WHILE语句来进行流程控制。

每个流程中可能包含一个单独语句,或者是使用BEGIN...END构造的复合语句,构造可以被嵌套。

1.IF语句

IF语句用来进行条件判断。根据是否满足条件,将执行不同的语句。其语法的基本形式如下:

  1. IF search_condition THEN statement_list
  2. [ELSEIF search_condition THEN statement_list] ...
  3. [ELSE statement_list]
  4. END IF
  5. 解析:
  6. 其中,search_condition参数表示条件判断语句;statement_list参数表示不同条件的执行语句。

注意:MYSQL还有一个IF()函数,他不同于这里描述的IF语句

例题:

  1. 1:根据输入的参数来判断age与1820的关系来确定是不是成年人
  2. DELIMITER$$
  3. CREATE FUNCTION f1(age int(10))
  4. RETURNS varchar(255)
  5. BEGIN
  6. IF age<18 THEN return '未成年人';
  7. ELSEIF age=20 THEN return '20岁了';
  8. ELSE return '成年人';
  9. END IF; #IF语句都需要使用END IF来结束。
  10. END$$
  11. DELIMITER;
  12. ->select f1(10);
  13. 结果为:未成年人
  14. 2:根据输入的工资来涨工资
  15. delimiter$$
  16. create function f2(salary int(10))
  17. returns int(10)
  18. begin
  19. declare aaa int(10) default 0; #同样可以使用局部变量和全局变量
  20. if salary<=3000 then return salary+500; #工资不高于3000,涨500
  21. elseif 3000<salary<=5000 then return salary+1000; #工资大于3000而不高于5000,涨1000
  22. else return salary+2000; #工资高于5000,涨2000
  23. end if;
  24. end$$
  25. delimiter;

IF语句都需要使用END IF来结束。

IF函数:

  1. 语法:IF(value,t,f)函数
  2. 例:
  3. select if((age)<18,'未成年人','成年人'from table_test;
  4. 解析:查询table_test表中的age列,如果age<18,则返回‘未成年人’,否认返回‘成年人’;

IFnull函数:

  1. IFNULL(value1,value2)函数
  2. 例:select ifnull(salary,0) from table_test;
  3. 解析:查询table_test表中的salary列,如果为null,则返回0

2.CASE语句(有两种格式)

CASE语句也用来进行条件判断,其可以实现比IF语句更复杂的条件判断。CASE语句的基本形式如下:

  1. CASE case_value
  2. WHEN when_value THEN statement_list
  3. [WHEN when_value THEN statement_list] ...
  4. [ELSE statement_list]
  5. END CASE
  6. 解析:
  7. 其中,case_value参数表示条件判断的变量;
  8. when_value参数表示变量的取值;
  9. statement_list参数表示不同when_value值的执行语句。
  10. 例:
  11. delimiter$$
  12. create function f1(damage int(10))
  13. returns varchar(255)
  14. begin
  15. case damage
  16. when 100 then return 'adc';
  17. when 90 then return 'ad';
  18. when 65 then return '坦克';
  19. else return 'ap';
  20. end case; #CASE语句都要使用END CASE结束
  21. end$$
  22. delimiter;

CASE语句还有另一种形式。该形式的语法如下:

  1. CASE
  2. WHEN search_condition THEN statement_list
  3. [WHEN search_condition THEN statement_list] ...
  4. [ELSE statement_list]
  5. END CASE
  6. 解析:
  7. 其中,search_condition参数表示条件判断语句;
  8. statement_list参数表示不同条件的执行语句。
  9. 例:
  10. delimiter$$
  11. create function f1(damage int(10))
  12. returns varchar(255)
  13. begin
  14. case
  15. when damage=100 then return 'adc';
  16. when damage=90 then return 'ad';
  17. when damage=65 then return '坦克';
  18. else return 'ap';
  19. end case; #CASE语句都要使用END CASE结束
  20. end$$
  21. delimiter;

下面是一个CASE语句的示例。代码如下:

  1. CASE age
  2. WHEN 20 THEN SET @count1=@count1+1;
  3. ELSE SET @count2=@count2+1;
  4. END CASE ;

代码也可以是下面的形式:

  1. CASE
  2. WHEN age=20 THEN SET @count1=@count1+1;
  3. ELSE SET @count2=@count2+1;
  4. END CASE ;

本示例中,如果age值为20,count1的值加1;否则count2的值加1。CASE语句都要使用END CASE结束。

注意:这里的CASE语句和“控制流程函数”里描述的SQL CASE表达式的CASE语句有轻微不同。这里的CASE语句不能有ELSE NULL子句

并且用END CASE替代END来终止!!

case表达式:

  1. 第一种:
  2. SELECT id,CASE
  3. WHEN damage<=60 THEN 'ap'
  4. WHEN damage<80 THEN 'ad'
  5. WHEN damage>80 THEN'adc'
  6. ELSE 0
  7. END
  8. FROM test3;
  9. 第二种:
  10. SELECT id,CASE damage
  11. WHEN 70 THEN 'ap'
  12. WHEN 85 THEN 'ad'
  13. WHEN 100 THEN'adc'
  14. ELSE 0
  15. END
  16. FROM test3;

 3.LOOP语句

LOOP语句可以使某些特定的语句重复执行,实现一个简单的循环。

但是LOOP语句本身没有停止循环的语句,必须是遇到LEAVE语句等才能停止循环。

LOOP语句的语法的基本形式如下:

  1. [begin_label:] LOOP
  2. statement_list
  3. END LOOP [end_label]
  4. 解析:
  5. 其中,begin_label参数和end_label参数分别表示循环开始和结束的标志,这两个标志必须相同,而且都可以省略;
  6. statement_list参数表示需要循环执行的语句。

下面是一个LOOP语句的示例:从1加到无穷,因为没有条件结束循环。代码如下:

  1. DELIMITER$$
  2. CREATE FUNCTION f3()
  3. RETURNS INT(10)
  4. BEGIN
  5. DECLARE x INT(10);
  6. declare y int(10);
  7. SET X=0;
  8. set y=1;
  9. -- 开始循环
  10. LOOP
  11. SET x=x+y;
  12. set y=y+1;
  13. END LOOP ; -- 结束循环
  14. RETURN X;
  15. END$$
  16. DELIMITER;
  17. 结果:
  18. 会一直执行,因为没有结束循环的条件

该示例循环执行1到无穷的操作。因为没有跳出循环的语句,这个循环成了一个死循环。

LOOP循环都以END LOOP结束。

4.LEAVE语句

LEAVE语句主要用于跳出循环控制。其语法形式如下:

  1. LEAVE label
  2. 解析:
  3. 其中,label参数表示循环的标志。

例1:从1加到99,代码如下

  1. DELIMITER$$
  2. CREATE FUNCTION f5()
  3. RETURNS INT(10)
  4. BEGIN
  5. DECLARE X INT(10);
  6. DECLARE Y INT(10);
  7. SET X=0;
  8. SET Y=1;
  9. -- 开始循环
  10. myloop:LOOP
  11. SET X=X+Y;
  12. SET Y=Y+1;
  13. IF Y=100 THEN LEAVE myloop;
  14. END IF; --记得结束if语句
  15. END LOOP myloop; -- 结束循环
  16. RETURN X;
  17. END$$
  18. DELIMITER;

5.iterate 语句

ITERATE语句也是用来跳出循环的语句。但是,ITERATE语句是跳出本次循环,然后直接进入下一次循环。

ITERATE语句只可以出现在LOOP、REPEAT、WHILE语句内。

ITERATE语句的基本语法形式如下:

  1. ITERATE label
  2. 其中,label参数表示循环的标志。

例子:从1加到99,但是不加2,代码如下

  1. DELIMITER$$
  2. CREATE FUNCTION f5()
  3. RETURNS INT(10)
  4. BEGIN
  5. DECLARE X INT(10);
  6. DECLARE Y INT(10);
  7. SET X=0;
  8. SET Y=1;
  9. -- 开始循环
  10. myloop:LOOP
  11. SET X=X+Y;
  12. SET Y=Y+1;
  13. IF Y=2 THEN ITERATE myloop;
  14. END IF; --如果是if语句,记得结束if语句
  15. IF Y=100 THEN LEAVE myloop;
  16. END IF; --如果是if语句,记得结束if语句
  17. END LOOP myloop; -- 结束循环
  18. RETURN X;
  19. END$$
  20. DELIMITER;

说明:LEAVE语句和ITERATE语句都用来跳出循环语句,但两者的功能是不一样的。

LEAVE语句是跳出整个循环,然后执行循环后面的程序。而ITERATE语句是跳出本次循环,然后进入下一次循环。

使用这两个语句时一定要区分清楚。

6.repeat 语句

REPEAT语句是有条件控制的循环语句。当满足特定条件时,就会跳出循环语句。REPEAT语句的基本语法形式如下:

  1. [begin_label:] REPEAT
  2. statement_list
  3. UNTIL search_condition
  4. END REPEAT [end_label]
  5. 其中,statement_list参数表示循环的执行语句;search_condition参数表示结束循环的条件,满足该条件时循环结束。

下面是一个REPEAT语句的示例。代码如下:

  1. delimiter$$
  2. create function f6()
  3. returns int(10)
  4. begin
  5. declare x int(10);
  6. declare y int(10);
  7. set x=0;
  8. set y=1;
  9. --开始循环
  10. repeat
  11. set x=x+y; --不要忘记加set
  12. set y=y+1;
  13. until y=101
  14. end repeat; --结束循环
  15. return x; --不要忘记return
  16. end$$
  17. delimiter;

该示例循环执行从1加到100,y值为101时结束循环。

REPEAT循环都用END REPEAT结束。

7.WHILE语句

WHILE语句也是有条件控制的循环语句。但WHILE语句和REPEAT语句是不一样的。

WHILE语句是当满足条件时,执行循环内的语句。

WHILE语句的基本语法形式如下:

  1. [begin_label:] WHILE search_condition DO
  2. statement_list
  3. END WHILE [end_label]
  4. 其中,search_condition参数表示循环执行的条件,满足该条件时循环执行;
  5. statement_list参数表示循环的执行语句。

下面是一个ITERATE语句的示例。代码如下:

  1. 1
  2. DELIMITER$$
  3. CREATE FUNCTION f11()
  4. RETURNS INT(10)
  5. BEGIN
  6. DECLARE X INT(10);
  7. SET X=1;
  8. -- 开始循环
  9. WHILE X<100
  10. DO
  11. SET X=X+1;
  12. END WHILE ; -- 结束循环
  13. RETURN X;
  14. END$$
  15. DELIMITER;
  16. 2
  17. DELIMITER$$
  18. CREATE FUNCTION f7(a INT)
  19. RETURNS VARCHAR (255)
  20. BEGIN
  21. DECLARE X INT;
  22. DECLARE Y INT;
  23. SET Y = a;
  24. -- 开始循环
  25. WHILE Y < 10 DO
  26. SET Y = Y + 1;
  27. END WHILE; -- 结束循环
  28. RETURN Y;
  29. END$$
  30. DELIMITER;
  31. 该示例循环执行count1的操作,count值小于100时执行循环。
  32. 如果count值等于100了,则跳出循环。WHILE循环需要使用END WHILE来结束。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/737982
推荐阅读
相关标签
  

闽ICP备14008679号