00:01
接着啊,咱们来学习下第15章叫做存储过程与函数啊,这个呢,其实完整的叫法呢,应该叫存储过程与存储函数,哎,这个大家要注意,实际上是两个内容,这个函数的话呢,完整的叫法呢,叫做存储函数。那前面的话呢,我们讲过视图了,作为呢,就是除了表之外的一个数据库对象,那么存储过程跟函数呢,也是新的我们要讲的这个数据库对象,这呢,相当于是两个内容对吧。那么一提到这个函数啊,大家应该不陌生啊,咱们这个讲SQ之前呢,大家上中学的时候呢,也没少学函数是吧?然后呢,我们讲这个SQ的时候呢,前面呢讲过这个叫单行函数,咱们也讲过呢,是不是叫聚合函数啊,那么这些函数呢,是系统呢已经提供现成的,咱们直接拿过来用呢就可以了。那关于说这些函数的这个底层逻辑呢,是什么样的,咱们可能没有具体的去关注,你比如说咱们计算两个日期这个之间的这个时间是吧,天数这个呢,咱们也没有去翻它底层源码看看是怎么做的,咱们知道怎么去调用就可以了,是这意思吧,那么我们这里边儿提到这个函数啊,其实相较于咱们前面讲这个函数来讲,这个指的就是用户自定义的函数。
01:14
前面呢是提供好的,这呢是我们自定义的啊,就是这么个区别。那么在函数里边啊,咱们是不是就可以把复杂的这个SQ的逻辑,咱们就封装到你这个函数里边,当你需要的时候呢,是不是直接拿回来调用就可以了呀。那这呢,就是我们所谓的这个叫哎,存储函数,OK,那存储过程是什么呢?那存储过程跟存储函数呢,其实最明显的区别就是函数咱们说一定会有返回值的。或者说咱们从中极的角度来讲呢,就函数一定会有,是不是因变量啊啊,比如说这呢,是我们说的一个函数啊,然后呢,我们这呢,一个变量X放进去,基于这个函数之后呢,我们出来一个结果,这就是函数的特征,那放在咱们讲的这个,嗯。这个MYSQL的函数当中,我们怎么理解呢?比如我们这里边有个函数呢,叫做四舍五入,咱们放进去一个123.45,然后round完以后呢,出来了是一个123,那出来的这个结果呢,我们就叫做一个返回的一个值,或者呢,我们称为呢就是一个因变量。
02:12
函数呢,是一定会有一个返回值的,那这是它的一个特征,而我们这个存储过程呢,它是可以没有这个返回值的,那这就是他俩的一个主要的一个区分点啊OK,那这呢其实是两个东西了,所以咱们下边讲解的话呢,咱们就先讲解一下这个存储过程,然后呢,咱们把存储过程呢,基本的这个点说清楚之后呢,咱们来讲一下这个叫存储函数。然后关于它们二者的相同点,比如说基本上结构是一样的啊,如何去查看他们呀,如何去修改和删除啊,咱们就放在一起来说了,最后呢,再看一下这个存储过程,存储函数使用上的一些这个争议。啊一些争议行,那首先的话呢,咱们就来给大家讲解一下,这个叫存储过程,那对应的英文呢,叫做store的procedure啊这个存储过程啊,这个呢,非常直译啊,直接的我们翻译过来就叫存储过程了。
03:04
那么他的思想呢?也非常简单,就是一组经过预先编译的色后语句的封装。那这里边儿呢,提到一个叫预先编译,就是咱们这个,呃,就是首先呢,就是大家呢,目前啊,因为还不是太熟嘛,你可以把这个存储过程跟函数呢,先都看成一个整体,就是一个函数啊,你先这样来理解啊,那相当于呢,我们在函数里边呢,你肯定就是写这个函数具体的是不是操作的这些细节了,对吧,那就相当于我们所谓的叫SQL逻辑,那写完以后的话呢,咱们把这个呃存储过程或者这个存储函数啊,咱们是预先呢存储在这个MYSQL的服务器上。那放到这个服务器上以后呢,它其实还帮我们做了一个预先的一个编译,那因因为我们写,因为我们在这个函数啊,或者存储过程里边写的这个SQL语句啊,在执行的时候呢,其实都需要呢,经过编译器的一个编译的,包括优化器的优化等等,这些都是我们下篇当中具体到时候给大家展开呢去说的这个内容。啊,下边里边呢,我们这不是呢,都会给大家去讲这个,呃,落叶架构是吧。
04:02
容辑架构啊,存储引擎啊,我们到时候会说它整个这样的一个里边的这个相关的一些结构啊,呃,这块呢,我们先大体上知道这么个事儿,那现在的话呢,就相当于我们把这个存储过程呢,就放在服务器上了,而且呢都预先编译好了,当我们需要的时候呢,直接用户呢,是不是通过客户端发送一个指令过去就行了呀。啊,你就比如说我们这是一个客户端,这呢是咱们这个数据库的服务器,然后呢,我们这个存储过程跟函数呢都已经放在这儿了,然后呢,用户只需要发送说我要执行哪个函数或者哪个存储过程,它直接呢就发送个指令,非常短的一个数据过来,然后直接调用我们这个服务器里边这个存储过程或者函数就可以了。啊,对吧,那这里边其实能够节省的时间呢,就是你看这就涉及到它的一些好处了,咱们是不是不需要呢,你像原来的时候我们要在这去写这个select语句呢,是不是要把这个语句整个传过来,现在呢,这个select语句一系列的都在服务器上了,不用我们去传输了,减少这个传输量了,哎,同时的话呢,我们这个都预先编译过了,也用不着呢,我们再去编译啊,还省去了一个编译的一个时间。
05:05
那同时的话呢,还简化了操作,这就涉及到了咱们不用自己去,呃这个吭哧吭哧写这么多产语句了,我直接封装到这个函数里边,直接一调函数就就完了,从这个角度来讲呢,好处有点像我们这个view是吧,像咱们这个视图。减少操作过程中的失误,提高效率啊,直接调函数嘛,然后减少了SQL语句呢,暴露在网上那个风险,提高了数据查询那个安全性,呃,因为呢,我们不需要在网络当中去传输我们的circle了,直接呢就在服务器上已经存在了啊,那自然而然的这个安全性呢就会更高,所以这个呢非常好理解啊。呃,那么刚才呢,我们也提到了视图这个概念,那有同学会想说,哎,这个跟视图是不是有点类似呀?那其实呢,这哥俩的思想啊,想法是完全不同的,哎,这点呢,大家要把握住。那你看我来给你讲啊,这个虽然说呢,这个函数存储函数也好,存储过程也好,它跟咱们说这个视图啊,都是很清晰啊,安全呀,减少网络传输啊等等,因为这个视图里边本身也没有存数据嘛,是吧,但是它跟视图主要不同点是啥呢?咱们视图啊,大家一定要把握这个点,咱们更多的呢是就是把它看成是一个虚拟的表,咱们通常不会针对于试图去做增删改的操作。
06:18
咱们主要针对这个视图呢,还是去做这个查询的。哎,咱们还是主要去做这个查询操操作的,哎,说白了就是我们就把它看成是一个虚拟的表了。啊去你的表了,然后呢,我们直接呢,去做一些这个这个查询就行,而存储过程呢,它主要呢,就是来存这个circle的。那存这个circle的,它内部的这个结构呢,是可以更复杂的,虽然说呢,我们视图里边就是存储起来此来语句,但存储过程呢,这个查询操作呢,一般也会多一点,但是除了查询之外呢,我们还可以写丰富的增删改啊,包括我们还可以在这个存储过程里边,下一章咱们还要讲啥呀,讲这个变量啊,流程控制啊,游标啊,科色是吧,哎,这个结构是非常丰富的。哎,就是存储过程里边这个SQL语句呢,它的结构是非常复杂的,它更多的看重的是什么呀,就是我们丰富的这个叫呃,SQL逻辑,而我们这个视图呢,就是主要看成是一张虚拟的表啊,所以他的想法是完全不同的啊,大家要去体会一下。
07:17
好,那么接下来这个存储过程跟我们这个函数的一个区别是什么呢?哎,主要区别呢,就是存储过程呢,没有返回值啊,把握住这一点呢就可以了啊OK,行,那么下面的话呢,我们就看一下这个存储过程,那讲这个存储过程创建之前啊,简单的我这块呢有一个分类,哎大家呢,可能上来一看,这个分类呢,稍微有点懵,诶稍微有点懵,这块的分类的标准是什么呢?主要呢是参照为咱们创建这个procedure,它在这个小框里边。咱们呢,去写这个参数的时候啊,哎,分成了几种情况。哎,分成了几种情况,哎,如果大家呢,之前没有接触过一些其他的编程语言的话呢,一上来我们就开始接触存储过程呢,你可能会稍微呃有点接触的慢一些啊,如果大家你学习过C语言的函数啊,学习过咱们Java的这个呃方法的话呢,那么你对于我们现在要讲的那个存储过程呢,可能理解起来就会更快一些。
08:12
啊,本身学编程语言都这样是吧,大家如果你学过Java,你再学Python啊,我估计呢,你上着班的情况下呢,一周时间Python也差不多就搞定了啊就是触类旁通嘛,是吧,那学个C,那学个C加加你再学Java呢,肯定也会快一些是吧,就同样的道理。好,那我们这里边怎么区分的呢?就这个小框里边放的呀,它叫做行参啊,或者叫行参列表,那么这个参数的话呢,我们是可以有这个修饰符的,这里边儿的修饰符呢,就叫in out,或者叫in out。啊要in out,根据这几个呢,我们来区分,那首先的话呢,我们没有参数,就是这里边儿呢,啥也不写,这呢是可以的,这就是一种情况,第二种情况呢,我们只有in。这个印的话呢,其实表达的就是一个入参,就是传入这个参数,你比如说我们想查询这个某一个呃姓名,员工的一个工资是多少,你需要传进来,这个员工的姓名传进来,你看我这块提到了传进来是不是就是in啊,呃这时候想表达就是这个参数是有参数的,我传进来了,然后暂时呢,我们没有out,所以它就没有返回了,而这out是什么呀?Out呢就是说我们得把它,诶再再再传出去。
09:18
啊,其实或者说我们把这个数据呢,其实主要呢,里边,比如我们想这个查询张三的这个公司,哎,你这块呢,传进来一个变量,然后这个变量呢,哎,我们就通过这个里边查询的方式呢,把这个值呢,就写到你这个alt这个变量里边了,你再去呢,查你这个out变量的那个值就就出来了。哎,这就是只有一个out的啊,注意这时候我们这个返回的话呢,大家你别理解成呢,跟咱们说,哎,这不刚才说没有返回值,这怎没有返回的,咱们讲函数的时候呢,是明明确确有一个return。啊,跟那个是不一样的啊,整体来讲你这不都是属于参数嘛,是吧,只不过这个参数是out的时候呢,我们需要把它这个传出去,然后我们再拿到那个值啊,还是有有一些区别的啊。好,然后呢,这是只有alt的,然后再一种呢,就是既有in又有alt的啊,但是这时候呢,它是两个不同的变量了,然后下边这个in in out的话呢,它是诶就是相当于合并在一个变量上了,那in奥的一个变量。
10:13
那这呢,其实就分成了这五种情况,大家可能现在听起来呢,有点迷迷糊糊的是吧,没有关系,咱们讲完这个基本语法之后呢,下边咱们就开始写这个具体的例子了啊,一写例子呢,这个你就清楚了。好,那么从这个语法结构上来看的话呢,这个存储过程你看哎哟还行是吧,不是太复杂,哎,我们创建什么呢?你就写create什么就可以了,Create存储过程呢,叫procedure啊,我们就这样写,下边呢,就是存储过程这个名,这个参数呢,咱们刚才讲过了啊,你看我这块呢,也专门又说了一遍是吧?诶说了一遍,那这里边呢,就是有个小细节,就是如果我们自己在定义变量的时候呢,你要是没有指明,没显示的写in或out,或者out默认的话呢,它就当成是in了。哎,就这个道理,然后接着后边这块也有这个参数类型,咱们前面呢,第12章是专门的讲了丰富的这个,诶MYSQ中的数据类型了是吧?哎,这个位置呢,都可以去使用的。
11:08
好,然后再往下面有一个叫characteristics啊,这个呢,翻译成中文呢,叫做特征,这个单词呢也很难写,这块呢是有点麻烦的。啊,有点麻烦的,就是这个特征呢,体现的是什么呀,咱们这块呢,可以快速的过一下啊,快速的过一下就是大家呢,如果你在实际开发当中啊,真的去需要写这个存储过程的时候呢,诶到时候你可以细节上再去多关注一下它啊你看因为你看我这个最后呢,是不是写了一个关于存储过程有个争议性是吧。啊,这是什么意思啊,就是有的公司呢,它是禁止去使用这个存储过程的,那阿里巴巴就是这样一个规范,那为什么呀,凭什么这个对人家这个存储过程这么不公平啊是吧?这个我们到时候先讲完这个存储过程,然后咱们再说,为什么阿里呢是禁止咱们使用这个存储过程。哎,同学可能看到这说说老师那哎挺好是吧,我就直接开始下一个视频了,这个反正你说禁止了我就不学了是吧。
12:01
也可以啊,那也是可以的啊,因为这个大家在需要的时候呢,你现在过来再去补也OK啊,也没有关系。行,那本身这个内容呢,其实也没多少啊,咱们这块呢,就给大家讲一下。好,所以说这块呢,关于这个呃,特征这块呢,咱们就得快速的给大家过一下啊,这个特征呢,我们可以设置的值是什么呢?那一组两组啊,三组,然后四组五组啊,有这五组啊,首先呢,这叫language circle,这个呢,就指明咱们下边呢,写的主要的就是这个存储过成体了,对吧?这个存储过程体的话呢,咱们是相当于是circle语句构成的,哎,表示呢,叫language circle啊,就是这个意思。然后呢,下边这块呢。有一个not,或者说你不写not的,嗯嗯,Deter啊,这是什么意思呢?就这个叫确定性的意思。啊,咱们不是学个单词叫determine是吧?哎这个呢就是确定性的意思,它就是指明你这个存储过程的执行的结果是不是确定的,你要是呢,哎,没有not呢,就是确定的,有个not呢,就是不确定的,你要没写没写默认就是有个not。
13:02
那确定不确定啥意思呢?就是我们要同呃执行这个存储过程的时候呢,每次执行这个存储过程输入的这个相同的这个输入呢,会得到相同的结果,那就是确定的。那要是这个相同的输入得到的结果是不一样的呢?那就是不确定的。你比如我们输入一个这个这个一个边界,然后呢,你返回这个边界范围内的一个随机数,那就是会有确定的和不确定的之分,是吧,OK。然后下边呢,是诶里边是包含circle的,还是没有circle的,还是说呢,我们这里边儿呢,是包含这个读操作的,还是包含这个写操作的啊就是这个意思。哎,就这个意思,OK啊,然后再往下呢,就circle quality这个就安全性,就我们定义的这个,呃,存储过程是只让定义者去使用呢,还是说呢,只要有权限的就都可以用呢。啊,就是这个区别,这个defender就谁定义的谁才可以用啊in worker呢,就是诶只要有权限的话呢,我就能用啊还是有区别的,诶默认情况下呢,如果我们不写这个circle security是这个,呃,它或者它的话呢,默认情况下呢,就是这个谁定义谁才可以用。
14:05
啊,你要别人也想用,那你这块呢,给他赋予权限就可以了。哎,就可以了。然后呢,下边这个呢叫哎comment,然后spring,哎这个呢,其实主要呢,就是来描述加上这个注释信息的啊说我们这个函数呢,这个过程呢,存储过程是做什么用的,哎这个呢,就是哎给他提供这个注释信息的啊了解一下就行啊其实整个来讲的话呢,其实也比较简单是吧,也比较简单。好,那么这个后边的话呢,呃,由一组这个。哎,相当于是这个你可以看到是这个小括号或者大括号的左边,这个是大括号的右边啊,叫begin end,中间呢,就是咱们电的这个存储过程,你到底要干什么,就在这里边呢去写,叫存储过程体,类似于呢,像我们Java或者是C语言当中的这个函数啊,或者叫方法呀,这个方法体或者叫函数体。行,这个呢,就是咱们关于呃,整体的一个简单的介绍啊,那么这个存储过程体的话呢,这个里边还涉及到这个变量的定义啊等等的,这个咱们放到下一章。
15:03
哎,其实咱们下一章呢,叫做变量流程控制和游标啊,其实也是基于咱们说的存储过程和函数来讲的,只不过呢,就是呃,在我们这一章讲解的基础上呢,就是里边的这个存储过程或者叫存储函数体呢,就更复杂了啊,可以去定义变量,可以去执行循环,执行分值结构,还可以去写这个游标是吧,就结构更复杂了,那这一章呢,我们先讲的就没有那么复杂。啊,还没有那么复杂的,所以这块呢,大家暂时呢先了解一下,我们下一章再具体去说。那这就是到这儿了,嗯,按说呢,说完了还不许写代码吗?哎,稍等一等,咱们再说一个东西啊,说完这个呢,咱们开始写这呢有一个单词,或者叫一个关键字啊,Di limit啊Di limit这个翻译过来呢,就是一个分割符的意思。分割符的意思,诶,为什么讲的它,它是干啥的呢?实际上呢,你看我这写了这么多东西啊,其实非常简单啊,非常简单啊,我直接说咱们拿一个例子给大家说一下,你就能明白了。
16:01
来,我就拿这个例子来给大家说。你看啊,嗯,本身呢,你先不考虑它,咱不是说要定一个存储过程吗?是不是我这呢就写了一个呀。哎,我就写了一个啊,那我们create create一个procedure,然后这呢就取个名参数也没有,咱们讲了有begin,有end end这块呢,你加一个,咱们正常来讲是不是就分号结束啊,哎,这样子的好,然后呢,在这个里边呢,咱们说就可以写这个具体的叫存储过程提了啊,就是一个一个的查语句,你这块该分号结束就结束啊,就是相应的这个执行语句呢,都得需要考虑用这个分号去结束的。那就这么着对吧,那我们这个写完这个函数以后呢,我们首先呢,是不是得运行一下,运行的话呢,先把这个,咱们说这是一个数据库对象啊,就像咱们前面提到的那个视图一样,是不是它得保存下来,然后在咱们这个以circleq要为例,咱们其实是能够看到的,你看。它是能够保存下来的是吧,就像我们前面的创建这个视图一样啊,所以呢,我们运营完以后呢,它这块是能看到你持这个持久化里边呢这个函数的。
17:03
那么大家你想我们这时候在创建的过程当中啊,咱们前面写查询的时候呢,是不是分号代表的就是结束是吧,如果我们要是把这个选中一执行的时候呢,它会报错,为啥呢?因为这里边儿呢,他会认为你这个分号呢,表示的是结束,所以呢,还没有走到end这块呢,我们就认为结束了,那显然没有结束,所以它就报错了。甚至说呢,我们这里边儿,你还有其他的一些语句,你想想一出现分号就结束了,那就不是我们想要的了。那怎么办解决这个问题啊,因为咱们不是说在这个MYSQ里边默认情况下呢,这个分号表示的就是结束的意思是吧,那怎么办呀,哎,这个limit呢,就出现了,说哎,我来搞定这个问题怎么着呀。呃,你不是MYSQL默认是分号表示结束吗?我呢就先指明啊,比如我这用个Dollar符来表示,我用Dollar符来表示。这个MYSQ当中的这个结束语句。那就是这个叫哎,Di limit,我们用这个Dollar来表示了,表示完以后的话呢,你下边再去执行,此时这个分号呢,它表达的就不再是一个结束的意思了啊,他就一顿往下走,走到哪结束呢,走到哪他找到这个倒乐符了,诶是不是就到这就结束了呀。
18:13
那就相当于是把我们这个整体呢,就作为一个整体出现了,而不是在这儿呢给结束了,好,那你呃,后边这块呢,我又加了一个Di limit,然后加了一个分号,什么意思啊,就是我们又改回去了,哎,方便呢,咱们后边呢,你要再写这个查语句啊,或者iner等等,有分号呢,表示的是还是结束的意思,所以呢,我们这块呢,先改过来,然后执行完以后呢,再给人家改回去,哎,就是这么个意思。但是至于说这块呢,用不用刀,用刀符还用什么呀,咱们也可以用这种符号都可以啊,或者我这块我想用两个刀符可不可以啊,哎,其实也行啊,这个意思,但是这块建议大家你不要用这个这个符号,因为这呢在咱们MYSQL也好,在其他编程语言中也好,是不是都表示的叫。这个叫什么转义词符的意思是吧,你别用刚才我说的那个符号啊就OK了,一般习惯上我们用的话就到符,还有这个这个双写线啊就OK了。
19:03
行,那这里的话呢,咱们把这个函数呢,基本的这个点呢,咱们就说清楚了,哎,下边的话呢,咱们来给大家呢去呃这个创建几个函数啊,我们这块呢,也体会体会一下啊,这个有不同的这个呃,分类的方式是吧?好,我们下边来讲解。
我来说两句