【存储过程】MySQL存储过程/存储过程与自定义函数的区别

---------------------------存储过程--------------------

语法:

创建存储过程:

CREATE [definer = {user|current_user}] PROCEDURE sp_name ([ proc_parameter [,proc_parameter ...]]) [ characteristics..] routime_body

其中:

proc_parameter : [IN|OUT|INOUT] parameter_name type

其中IN表示输入参数,OUT表示输出参数,INOUT表示既可以输入也可以输出;param_name表示参数名称;type表示参数的类型

存储过程体中可以使用自定义函数(UDF)中使用的复合结构/流程控制/SQL语句/自定义变量等等内容,

调用存储过程:

CALL sp_name ([ proc_parameter [,proc_parameter ...]])

CALL sp_name 

说明:当无参时,可以省略"()",当有参数时,不可省略"()"

存储过程修改:

ALTER语句修改存储过程只能修改存储过程的注释等无关紧要的东西,不能修改存储过程体,所以要修改存储过程,方法就是删除重建!

删除存储过程:

DROP PROCEDURE [IF EXISTS] sp_name

示例:

创建无参存储过程:

delimiter //
CREATE PROCEDURE showTime()
BEGIN
SELECT now();
END//
delimiter ;CALL showTime;

作用:显示当前时间,没什么实际意义

创建含参存储过程:

只有一个IN参数

delimiter //
CREATE PROCEDURE seleById(IN uid SMALLINT UNSIGNED)
BEGIN
SELECT * FROM son WHERE id = uid;
END//
delimiter ;call seleById(2);

包含IN参数和OUT参数

delimiter //
CREATE PROCEDURE deleteById(IN uid SMALLINT UNSIGNED, OUT num SMALLINT UNSIGNED)
BEGIN
DELETE FROM son WHERE id = uid;
SELETE row_count() into num;
END//
delimiter ;call seleById(2,@changeLine);
SELETE @changeLine;

说明:创建存储过程deleteById,包含一个IN参数和一个OUT参数.调用时,传入删除的ID和保存被修改的行数值的用户变量@changeLine,select @changeLine;输出被影响行数.

 

 

 

附一个根据时间修改状态的存储过程:

DELIMITER $$USE `exam9`$$DROP PROCEDURE IF EXISTS `updateStatus`$$CREATE DEFINER=`root`@`localhost` PROCEDURE `updateStatus`()
BEGINUPDATE exam SET `status`="已结束" WHERE  `status` != "已结束" AND  (NOW() - endTime)>0  ;UPDATE exam  SET `status`="正在答题"  WHERE   `status` != "已结束" AND ( NOW() - startTime)>=0 AND  (NOW() - endTime)<=0;UPDATE haulinfo SET bigStatus="已结束" WHERE  bigStatus != "已结束" AND  (CURDATE() - bigEndDate)>0; UPDATE haulinfo SET bigStatus="进行中" WHERE  (CURDATE() - bigEndDate)<=0 AND  (CURDATE() - bigBeginDate)>=0;UPDATE exam SET bigStatus=(SELECT bigStatus FROM haulinfo WHERE bigId=exam.bigId);
END$$DELIMITER ;

 

 

 

 

区别:

存储过程与自定义函数的区别:存储过程实现的过程要复杂一些,而函数的针对性较强;存储过程可以有多个返回值,而自定义函数只有一个返回值;存储过程一般独立的来执行,而函数往往是作为其他SQL语句的一部分来使用;
存储过程存在的必要性(好处):

存储过程说白了就是把经常使用的SQL语句或业务逻辑封装起来,预编译保存在数据库中,当需要的时候从数据库中直接调用,省去了编译的过程.
提高了运行速度;
同时降低网络数据传输量(你觉得传一堆SQL代码快,还是传一个存储过程名字和几个参数快???)

 

 

---------------------------函数用法--------------------

自定义函数 (user-defined function UDF)就是用一个象ABS() 或 CONCAT()这样的固有(内建)函数一样作用的新函数去扩展MySQL。

所以UDF是对MySQL功能的一个扩展

创建和删除自定义函数语法:

创建UDF:

  CREATE [AGGREGATE] FUNCTION function_name(parameter_name type,[parameter_name type,...])

  RETURNS {STRING|INTEGER|REAL}

  runtime_body

简单来说就是:

  CREATE FUNCTION 函数名称(参数列表)

  RETURNS 返回值类型

  函数体

删除UDF:

  DROP FUNCTION function_name

调用自定义函数语法:

  SELECT function_name(parameter_value,...)

语法示例:

创建简单的无参UDF

CREATE FUNCTION simpleFun()RETURNS VARVHAR(20) RETURN "Hello World!";

说明:

UDF可以实现的功能不止于此,UDF有两个关键点,一个是参数,一个是返回值,UDF可以没有参数,但UDF必须有且只有一个返回值

在函数体重我们可以使用更为复杂的语法,比如复合结构/流程控制/任何SQL语句/定义变量等等

复合结构定义语法:

在函数体中,如果包含多条语句,我们需要把多条语句放到BEGIN...END语句块中

DELIMITER //
CREATE FUNCTION IF EXIST deleteById(uid SMALLINT UNSIGNED) 
RETURNS VARCHAR(20) 
BEGIN
DELETE FROM son WHERE id = uid;
RETURN (SELECT COUNT(id) FROM son);
END//

修改默认的结束符语法:

DELIMITER // 意思是修改默认的结束符";"为"//",以后的SQL语句都要以"//"作为结尾

特别说明:

UDF中,REURN语句也包含在BEGIN...END中

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

DECLARE var_name[,varname]...date_type [DEFAULT VALUE];

简单来说就是:

DECLARE 变量1[,变量2,... ]变量类型 [DEFAULT 默认值]

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

示例:

DELIMITER //
CREATE FUNCTION addTwoNumber(x SMALLINT UNSIGNED, Y SMALLINT UNSIGNED) 
RETURNS SMALLINT
BEGIN
DECLARE a, b SMALLINT UNSIGNED DEFAULT 10;
SET  a = x, b = y;
RETURN a+b;
END//

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

为变量赋值语法:

SET parameter_name = value[,parameter_name = value...]

SELECT INTO parameter_name

eg: 

...在某个UDF中...
DECLARE x int;
SELECT COUNT(id) FROM tdb_name INTO x;
RETURN x;
END//

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

SET @param_name = value

SET @allParam = 100;
SELECT @allParam;

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

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

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

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

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

1.IF语句

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

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

其中,search_condition参数表示条件判断语句;statement_list参数表示不同条件的执行语句。

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

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

IF age>20 THEN SET @count1=@count1+1;  
ELSEIF age=20 THEN SET @count2=@count2+1;  
ELSE SET @count3=@count3+1;  
END IF; 

该示例根据age与20的大小关系来执行不同的SET语句。

如果age值大于20,那么将count1的值加1;如果age值等于20,那么将count2的值加1;

其他情况将count3的值加1。IF语句都需要使用END IF来结束。

2.CASE语句

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

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

其中,case_value参数表示条件判断的变量;

when_value参数表示变量的取值;

statement_list参数表示不同when_value值的执行语句。

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

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

其中,search_condition参数表示条件判断语句;

statement_list参数表示不同条件的执行语句。

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

CASE age 
WHEN 20 THEN SET @count1=@count1+1; 
ELSE SET @count2=@count2+1; 
END CASE ; 

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

CASE 
WHEN age=20 THEN SET @count1=@count1+1; 
ELSE SET @count2=@count2+1; 
END CASE ; 

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

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

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

 

3.LOOP语句

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

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

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

[begin_label:] LOOP 
statement_list 
END LOOP [end_label] 

其中,begin_label参数和end_label参数分别表示循环开始和结束的标志,这两个标志必须相同,而且都可以省略;

statement_list参数表示需要循环执行的语句。

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

add_num: LOOP  
SET @count=@count+1;  
END LOOP add_num ; 

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

LOOP循环都以END LOOP结束。

 

4.LEAVE语句

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

LEAVE label 

其中,label参数表示循环的标志。

 

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

add_num: LOOP 
SET @count=@count+1; 
IF @count=100 THEN 
LEAVE add_num ; 
END LOOP add_num ; 

该示例循环执行count加1的操作。当count的值等于100时,则LEAVE语句跳出循环。

 

5.ITERATE语句

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

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

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

ITERATE label 

其中,label参数表示循环的标志。

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

复制代码
add_num: LOOP 
SET @count=@count+1; 
IF @count=100 THEN 
LEAVE add_num ; 
ELSE IF MOD(@count,3)=0 THEN 
ITERATE add_num; 
SELECT * FROM employee ; 
END LOOP add_num ; 
复制代码

该示例循环执行count加1的操作,count值为100时结束循环。如果count的值能够整除3,则跳出本次循环,不再执行下面的SELECT语句。

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

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

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

 

6.REPEAT语句

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

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

其中,statement_list参数表示循环的执行语句;search_condition参数表示结束循环的条件,满足该条件时循环结束。

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

REPEAT 
SET @count=@count+1; 
UNTIL @count=100 
END REPEAT ; 

该示例循环执行count加1的操作,count值为100时结束循环。

REPEAT循环都用END REPEAT结束。

 

7.WHILE语句

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

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

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

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

其中,search_condition参数表示循环执行的条件,满足该条件时循环执行;

statement_list参数表示循环的执行语句。

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

WHILE @count<100 DO 
SET @count=@count+1; 
END WHILE ; 

该示例循环执行count加1的操作,count值小于100时执行循环。

如果count值等于100了,则跳出循环。WHILE循环需要使用END WHILE来结束。

 

转载于:https://www.cnblogs.com/qlqwjy/p/7920012.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/370407.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java死锁故障排除和解决

JavaOne年度会议的一大优点是&#xff0c;主题专家介绍了几个技术和故障排除实验室。 其中的一个实验室今年特别吸引了我的注意力&#xff1a;“ HOL6500-查找和解决Java死锁 ”&#xff0c;由Java冠军Heinz Kabutz提出 。 这是我在该主题上看到的最好的演示之一。 我建议您自己…

3. HTML中的容器标签

什么是容器标签&#xff1f;在HTML开发中我们常常会使用一类标签作为容器放置一些内容&#xff0c;我们把这类标签称之为容器标签&#xff0c;可以作为容器标签的包括列表标签、表格标签、框架标签、布局标签&#xff0c;在这里我们就来总结下这些内容。 列表标签 1 <!-- 无…

GitHub上Java的Bloom Bloom实现

布隆过滤器是集数据结构的一种 。 对于那些不了解的对象&#xff0c;“设置数据结构”仅包含一个主要方法。 它仅用于确定特定元素是否包含在一组元素中。 大多数数据结构&#xff08;例如Hash Map &#xff0c; Linked List或Array &#xff09;都可以相当轻松地创建此函数。 …

ni软件管理器_NI 技术支持丨我的 NI 硬件设备不能被识别,怎么办?Windows

这篇指南可以帮助您解决在您的 Windows 系统上无法识别您的 NI 硬件有关的问题。症状包括以下几种情况&#xff1a;连接至 USB 端口时&#xff0c;硬件上的 LED 灯不亮/不闪烁。连接至 USB 后已连接设备的 LED 灯持续闪烁。仅限音频接口&#xff1a;该设备在音频应用程序或 Win…

在Java应用程序中使用密码学

这篇文章描述了如何使用Java密码体系结构 &#xff08;JCA&#xff09;&#xff0c;该体系结构使您可以在应用程序中使用密码服务。 Java密码体系结构服务 JCA提供了许多加密服务&#xff0c;例如消息摘要和签名 。 这些服务可以通过特定于服务的API来访问&#xff0c;例如Me…

CSS学习笔记-04 a标签-导航练习

个人练习&#xff0c;各位大神勿笑 。。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta http-equiv&qu…

深度学习loss值变为0_利用TensorFlow2.0为胆固醇、血脂、血压数据构建时序深度学习模型(python源代码)...

背景数据描述胆固醇、高血脂、高血压是压在广大中年男性头上的三座大山&#xff0c;如何有效的监控他们&#xff0c;做到早发现、早预防、早治疗尤为关键&#xff0c;趁着这个假期我就利用TF2.0构建了一套时序预测模型&#xff0c;一来是可以帮我预发疾病&#xff0c;二来也可以…

在Spring MVC Web应用程序中使用reCaptcha

CAPTCHA是一种程序&#xff0c;可以生成人类可以通过的测试并对其进行评分&#xff0c;而计算机程序“ 不能 ”通过。 所采取的策略之一是向用户显示具有扭曲文本的图像&#xff0c;并且用户应在输入区域中书写文本。 如果显示的文字与用户输入的文字相同&#xff0c;则我们可以…

课时109.外边距合并现象(掌握)

我们先写一个案例&#xff0c;通过案例来了解 它们之间的水平距离就是两个间距的和 我们看完水平再来看垂直方向 在默认布局的垂直方向上&#xff0c;默认情况下外边距是不会叠加的&#xff0c;会出现合并现象&#xff0c;谁的外边距比较大就听谁的 本文转载于:猿2048➜https:…

纯 CSS实现三角形

最近项目上做评论回复&#xff0c;设计师提高交互性特意设计了小三角&#xff0c;如下&#xff1a; 下面介绍一下实现效果的css方法&#xff1a; 1.border 通过设置上下左右border宽度来实现。 首先查看一下全部设置的效果&#xff1a; <style>   .triangle{     w…

Spring MVC表单验证(带批注)

这篇文章提供了一个简单HTML表单验证示例。 它基于带有注释的Spring MVC示例。 该代码可在GitHub的Spring-MVC-Form-Validation目录中找到。 数据 在此示例中&#xff0c;我们将使用bean和JSR303验证批注&#xff1a; public class MyUser {NotNullSize(min1,max20)private …

课时106.边框练习(理解)

让我们做出来如下的样式&#xff1a; 1.首先看下有几个边框&#xff0c;就做几个div&#xff0c;用简单方法div.box$*6 tab键 2.然后给它们设置宽高 3.然后依此来做边框 第一个&#xff1a;有四种方法&#xff0c;第一种最简单 第二个&#xff1a;有两种方法&#xff0c;第二…

课时105.边框属性下(掌握)

2.3连写&#xff08;分别设置四条边的边框&#xff09; border-width:上 右 下 左; border-style:上 右 下 左; border-color:上 右 下 左; 注意点&#xff1a; 1.这三个属性的取值是按顺时针来赋值的 也就是按照上右下左来赋值&#xff0c;而不是按照日常生活…

新mac 下第一次 安装 mongodb 步骤

新入手mac&#xff0c;安装mongo步骤记录&#xff1a;不建议使用网上的brew安装方法&#xff0c;因为试了半天没有成功&#xff0c;应该是新版本限制比较多&#xff01; 从mongodb官网下载mac版本mongo&#xff1a; 1.访问MongoDB官方下载地址 http://www.mongodb.org/download…

201621123065《JAVA程序设计》第11周学习总结

1. 本周学习总结 2. 书面作业 1. 源代码阅读&#xff1a;多线程程序BounceThread 1.1 BallRunnable类有什么用&#xff1f;为什么代码中需要调用Thread.sleep进行休眠&#xff1f; BallRunnable类实现Runnable接口&#xff0c;支持多线程&#xff1b;调用Thread.sleep进行休眠则…

vue使用v-for循环,动态修改element-ui的el-switch

在使用element-ui的el-switch中&#xff0c;因为要用v-for循环&#xff0c;一直没有成功&#xff0c;后来仔细查看文档&#xff0c;发现可以这样写 <el-switch v-for"(item, key) in list" v-model"item.is" :key"key" :active-value"…

前端加按钮将图片另存为_Windows 10系统如何将自己的照片制作成文件夹图标

我们大家都在电脑上建有很多文件夹&#xff0c;有时候查找自己需要的资料文件夹时不太容易&#xff0c;很浪费时间。如果将自己的照片作为常用文件夹的图标&#xff0c;看起来醒目查找时也更为方便些。下面就介绍具体的操作教程。一、将照片格式转换为图标文件格式在电脑上将图…

利用css transition属性实现一个带动画显隐的微信小程序部件

我们先来看效果图 像这样的一个带过渡效果的小部件在我们实际开发中的应用几率还是比较大的&#xff0c;但是在开发微信小程序的过程中可能有的小伙伴发现transition这个属性它不好使&#xff08;下面说明&#xff09;所以我们这个时候会考虑去使用微信官方提供的wx.createAnim…

c语言学生管理系统链表(dev vs2012下可以运行)

struct student { char name[10]; char sex[5]; long int num;//学号 int xuhao; int age; float score[3]; float averange; char DJ;//存放等级哦 struct student *next;};//定义结构体变量保存 名字 性别 年龄 成绩] 结构体声明int n;//存放学生人数int man;//存放统计的男生…

抽象工厂设计模式解释

抽象工厂设计模式是工厂设计模式的另一种形式。 这种模式可以被视为“超级工厂”或“工厂工厂”。 抽象工厂设计模式&#xff08;属于“四人帮”的一部分&#xff09;属于“创新设计模式”类别&#xff0c;它提供了一种封装一组具有公共链接的工厂的方法&#xff0c;而无需突出…