当前课程知识点:数据库系统原理与开发 >  第6章 数据库应用编程 >  6.2 数据库存储过程 >  6.2 数据库存储过程

返回《数据库系统原理与开发》慕课在线视频课程列表

6.2 数据库存储过程在线视频

下一节:6.3 数据库触发器

返回《数据库系统原理与开发》慕课在线视频列表

6.2 数据库存储过程课程教案、知识点、字幕

同学们好

我是数据库主讲教师陈安龙

今天给大家介绍6.3节的数据库存储过程

本节的主要内容

要求大家了解存储过程的概念

掌握存储过程创建 删除的方法

掌握存储过程的执行方法

掌握PostgreSQL的PL/SQL基本语法

理解存储过程的优缺点

我们首先来看一下什么是存储过程

存储过程顾名思义是存储在数据库的一种对象

该对象是由一组能完成特定功能的SQL语句的集合所构成

是把经常会被重复使用的SQL语句逻辑块封装起来

经编译后 存储在数据库服务器端

当被再次调用时 就不需要再次编译

当客户端连接到数据库时

用户就通过指定存储过程的名字并给出参数

数据库就可以找到相应的存储过程予以调用

下面我们看一下我们如何来创建存储过程

不同的数据库系统创建存储过程的语法存在着一定的差异

许多数据库为创建存储过程和创建函数提供不同命令

如ORACLE、MySQL、SQL SERVER等数据库

使用CREATE PRECEDURE命令创建存储过程

同时他们还提供了创建函数的方法

使用CREATE FUNCTION创建函数

PostgreSQL将函数和存储过程都统一为函数

我们在这里把它称为存储过程

它使用的CREATE FUNCTION命令来创建的

我们下面看一下创建存储过程的语法

提供了CREATE FUNCTION 是基本的命令

OR REPLACE是关键字

大家看一下AS后跟了两个$符号

这个符号主要是用于声明存储过程的实际代码的开始

也就是存储过程的代码从哪里开始

双$符号是不能省略的

接下来就是声明存储过程的局部变量

接下来是BEGIN END 是存储过程的函数体的语句

就写在这里面

最后结束时有两个$符号结尾的

这两个$符号是标志存储过程的实际代码已经结束

关键字 LANGUAGE指明存储过程是采用什么语言来写

我们下面看一下前面有几个参数

name是指的要创建的存储过程的名字

OR REPLACE关键字的功能

主要是当其存储过程在数据库中存在时

如果没有or replace时 就会出现错误提示

告诉你存储过程已经存储

如果加上这个关键字

将会覆盖同名的已有的存储过程

现在所创建存储过程的代码来替换原有的存储过程

argmode这一个参数主要是存储过程参数的模式的指定

这个地方可以指定为IN OUT

in是指明存储过程的参数是输入参数

如果参数前面是out

说明是一个返回值的参数

如果前面是INOUT 缺省值是IN

argmode:存储过程参数的模式可以为IN、OUT

或INOUT代表参数既可以作为输入值

也可以作为返回值

缺省时或者不指定时它就是IN

argname是指定形式参数的名字

RETURNS是返回值

也就是存储过程执行完了之后

可以返回一个值

也可以用RETURNS TABLE返回一个二维表

也就是数据库存储过程不仅仅返回单个的值

而且可以返回一张表

表的记录返回给应用

下面我们看一个创建存储过程的示例

创建一个名为countRecords()的存储过程

统计STUDENT表的记录数

这个存储过程的名字叫countRecord

是可以覆盖已有的存储过程

括号里没参数 说明存储过程没有参数

returns integer指明返回整数值

$count$指明存储过程的开始

下面是声明一个count变量

类型为integer BEGIN END之间的语句

是统计student表的记录

将统计的值放入count变量

然后通过return返回

最后$count$后面的LANGUAGE的plpgsql指明

该存储过程是用postgreSQL的pl/SQL语句编写的

下面我们来存储过程编写好之后如何执行它

程序员可以在数据库查询管理器的窗口中执行存储过程

下面的语法用select后面跟上存储过程的名字

括号里面是实参 如果没有参数

括号里面为空 但是括号不能省略

或者采用select * from 存储过程名字

再跟上括号存储过程的参数

这种执行存储过程的方式好像在执行查询语句一样

比如说 我们执行刚才的存储过程

用select跟上存储过程

就可以执行刚才创建的存储过程

或者 select * from countRecords()来执行它

这两种方式都可以

如果程序员需要存储过程调用其它存储过程

语法形式可以采用

selectinto 后面跟一个用户自定义变量

from 我的存储过程名带上实参

下面假设我们新定义存储过程 testExec

这个存储过程返回整型类型

下面定义rec变量

在该存储过程中调用刚才的countRecords存储过程

select into rec countRecords中into rec

是将执行存储过的值放到rec变量里

大家注意一下 如果不关心countRecords的返回值

则可用 PERFORM 调用countRecords存储过程

来代替刚才用select执行存储过程

后面返回结果

LANGUAGE plpgsql是指明是plpgsql语言编写的存储过程

下面看一下删除存储过程

如果程序员需要删除存储过程的语法是什么

删除存储过程用DROP FUNCTION

参数 IF EXISTS是如果指定的存储过程不存在

那么发出提示信息

如果存储就直接删掉

name是要删除的存储过程名字

参数的模式:它有输入参数 输出参数 输入输出参数

大家注意 实际并不注意OUT参数

因为判断存储过程只需要输入参数

因为判断函数的身份只需要输入参数的数据类型

参数的名字 大家注意一下

实际上并不注意参数的名字

argtype是存储过程参数的类型

CASCADE是级联删除依赖于存储过程的对象

如果某触发器依赖该存储过程

这时也会删除依赖于它的触发器

RESTRICT是指如果有其它对象依赖该存储过程

则拒绝执行删除该存储过程命令

假如需要删除前面定义的存储过程

我们就可以执行DROP FUNCTION IF EXISTS testExec

在前面定义的存储过程没有参数

所有括号里是空的

现在我们给大家介绍PL/SQL语句

前面的SQL语言是结构化查询语言

而PL/SQL是过程化的查询语言

P是代表precedure L是代表Language

是过程化查询语言

支持循环 条件多分支等语法

我们下面介绍PL/SQL的基本语法

第一声明变量使用关键字declare 声明变量

前面是变量名

后面是变量类型

大家注意:它的声明变量的顺序和其它语言的不同

比如说C语言声明变量

变量类型是在前面

变量名是在后面

但是大家要注意

如果我们声明变量为记录型

这时可以使用RECORD 关键字声明变量为记录型

record关键字仅仅只是一个占位符 它告诉数据库

该变量将要用于存储某个数据库表的记录

这个变量的结构与存储数据库表的记录的结构

是相对应的我们声明rec变量为记录型

count变量为整型

我们来看一下PL/SQL的条件语句

在PL/pgSQL中有以下三种形式的条件语句

与其他高级语言的条件语句意义相同

第一种形式是 IF-THEN 满足if后面的条件

就执行then后面的语句

如果为假就跳到endif后面的语句

第二种形式是 IF-THEN-ELSE两个分支

如果满足if后面的条件

就执行then后面的语句

如果不满足将执行else后面的语句

第三种形式是 IF-THEN-ELSIF-ELSE

如果满足if后面的条件

就执行then后面的语句

如果不满足将判断elseif后面的条件

如果满足就执行then后面的语句

不满足就执行后面的语句

最后一个else只有在前面所有条件

不满足时才执行最后else的语句

下面我们来看循环语句

第一种采用了LOOP关键字

首先遇到LOOP语句 执行下面的语句

遇到END LOOP就返回继续执行

label是前面定义的标签

将返回到标签地方

一般不写label第二个关键字是EXIT

退出循环 when是指满足某个条件的时候

退出所在的循环

请看下面的例子

loop 和end loop中间的第一句count变量自加1

然后判断count是否大于100

大于100就退出循环

跳到endloop后面的语句执行

如果不大于100

继续循环执行count=count+1

直到count>100为止

下面我们看第三个关键字continue

当其满足条件时

继续执行循环体

但需要注意 当满足条件时

不执行continue后的count=count+1

直接到循环开始执行第一个count=count+1

然后exit when判断是否大于100
直接到循环开始执行第一个count=count+1

然后exit when判断是否大于100

大于100后就退出循环在continue处

如果count大于50时

就要执行两处的count=count+1

while循环语句与前面的loop不一样

while跟了一个表达式

当其表达式为真时

就执行loop和end loop中间的语句

前面多了while条件表达式

例如:当amount_owed > 0 和 balance > 0

在执行loop循环的语句

for循环语句

for循环中for里面有变量后有IN跟一个表达式

也就是变量值依次取in表达式中的值

就执行这个循环

大家看一下这个例子

i in 1...10表示i依次取1到10

raise notice'i is %',%是占位符

依次输出1到10

下面大家看一下

如果用in reverse

是按照后面指定顺序反向处理

变量命令

当其循环语句里是查询语句时

用for后面跟变量 in 查询语句loop endloop

一直要遍历到查询结果都处理完

申明了一个变量 rec record

rec是记录型的变量

for rec IN SELECT sid sname FROM student

从学生表中查询出学生的学号和学生的姓名

查询之后返回结果集

rec的结构和查询结果的结构一样

循环把结果集的记录一条一条地取到rec中输出出来

如何输出

用类似C语言的printf的raise notice

打印输出rec.sid,rec.sname

直到所有记录都打印

下面看看存储过程的优缺点

首先我们看它有什么优点

使用存储过程可以减少网络通信量

当需要大量数据库记录来计算时

把计算写在存储过程中

存储过程存储在服务器上存储过程的处理

是在服务器上执行的

这样就减少了在网络上传输大量数据的通信量

只需要在网络上传递存储过程的参数和返回的结果

第二 执行速度更快

因为服务器的性能都比较好

第三 更强的适应性

因为我们把业务上容易变化的部分写在存储过程中

但业务发生变化时

高级语言的程序不需要改变

只需要改变存储过程

第四 降低了业务实现与应用程序的耦合

业务处理可以使用存储过程来实现

可以降低应用程序与业务实现的耦合

第五 可以降低了开发的复杂性

通过合理地分解设计确认哪些业务在存储过程中

哪些业务在应用程序客户端实现

设计得合理 就可以降低复杂性

第六 它可以保护数据库元信息

因为存储过程可以隐藏一些数据库的元信息

应用程序不需要了解数据库元信息

起到保护作用

第七 可以增强数据库的安全性

因为存储过程存储在数据库中

可以通过数据库的权限管理

来授予用户对存储过程访问权限

如果用户没有对存储过程的访问权限

就不能访问对应的数据库的数据

这样就增加了对数据库的保护

提高了数据库的安全性

下面我们看一下使用存储过程的缺点

第一 SQL本身是一种结构化查询语言

而存储过程本质上是过程化的程序

面对复杂的业务逻辑

过程化处理逻辑相对比较复杂

而SQL语言的优势是面向数据查询而非业务逻辑的处理

这时使用存储过程很难发挥SQL的优势

第二 如果存储过程的参数或返回数据发生变化

不但需要修改存储过程的代码

而且还需要更新主程序调用存储过程的代码

第三 开发调试比较复杂

由于缺乏支持存储过程的集成开发环境

不像高级语言有集成开发环境

现在还很少有存储过程的开发环境

这样调试比较困难

需要程序员有一定的存储过程开发经验

才能开发出性能优良的存储过程

第四 可移植性差

因为不同数据库语言的语法存在较大差异

这时要把一个应用迁移到另外数据库系统上

需要重新开发存储过程

因此 存储过程的移植性比较差

所以 我们在具体开发中

就要考虑什么样的功能在存储过程中

需要设计者做权衡实现什么样的功能在应用程序客户端实现

数据库系统原理与开发课程列表:

第1章 数据库系统概论

-1.1 数据库及其系统概念

--1.1 数据库及其系统概念

-1.2 数据库技术发展

--1.2 数据库技术发展

-1.3 数据库应用系统

--1.3 数据库应用系统

-1.4 典型数据库管理系统

--1.4 典型数据库管理系统

-1.5 PostgreSQL对象-关系数据库系统软件

--1.5 PostgreSQL对象-关系数据库系统软件

-第1章 数据库系统概论--本章单元测试

-第1章 数据库系统概论--本章重点问题讨论

第2章 数据库关系模型

-2.1 关系及其相关概念

--2.1.1关系及其相关概念-1

--2.1.2关系及其相关概念-2

-2.2 关系模型原理

--2.2.1关系模型原理-1

--2.2.2关系模型原理-2

-2.3 PostgreSQL数据库关系操作实践

--2.3 PostgreSQL数据库关系操作实践

-第2章 数据库关系模型--本章单元测试

-第2章 数据库关系模型--本章重点问题讨论

第3章 数据库操作SQL语言

-3.1 SQL语言概述

--3.1 SQL语言概述

-3.2 数据定义SQL语句

--3.2.1数据定义SQL语句-1

--3.2.2数据定义SQL语句-2

--3.2.3数据定义SQL语句-3

-3.3 数据操纵SQL语句

--3.3 数据操纵SQL语句

-3.4 数据查询SQL语句

--3.4.1单表数据查询

--3.4.2 内置函数与分组统计

--3.4.3 多表关联查询

-3.5 数据控制SQL语句

--3.5 数据控制SQL语句

-3.6 视图SQL语句

--3.6 视图SQL语句

-3.7 PostgreSQL数据库SQL实践

--3.7 PostgreSQL数据库SQL实践

-第3章 数据库操作SQL语言--本章单元测试

-第3章 数据库操作SQL语言--本章重点问题讨论

第4章 数据库设计与实现

-4.1 数据库设计概述

--4.1 数据库设计概述

-4.2 E-R模型方法

--4.2.1 E-R模型方法-1

--4.2.2 E-R模型方法-2

-4.3 数据库建模设计

--4.3.1 数据库建模设计-1

--4.3.2 数据库建模设计-2

-4.4 数据库规范化设计

--4.4.1 数据库规范化设计-1

--4.4.2 数据库规范化设计-2

-4.5 数据库设计模型SQL实现

--4.5 数据库设计模型SQL实现

-4.6 基于Power Designer的数据库设计建模实践

--4.6 基于Power Designer的数据库设计建模实践

-第4章 数据库设计与实现--本章单元测试

-第4章 数据库设计与实现--本章重点问题讨论

第5章 数据库管理

-5.1 数据库管理概述

--5.1 数据库管理概述

-5.2 事务管理

--5.2 事务管理

-5.3 并发控制

--5.3.1 并发控制-1

--5.3.2 并发控制-2

-5.4 安全管理

--5.4.1 安全管理-1

--5.4.2 安全管理-2

-5.5 数据库备份与恢复

--5.5 数据库备份与恢复

-5.6 PostgreSQL数据库管理项目实践

--5.6 PostgreSQL数据库管理项目实践

-第5章 数据库管理--本章单元测试

-第5章 数据库管理--本章重点问题讨论

第6章 数据库应用编程

-6.1 数据库连接技术

--6.1.1 数据库连接技术-1

--6.1.2 数据库连接技术-2

-6.2 数据库存储过程

--6.2 数据库存储过程

-6.3 数据库触发器

--6.3 数据库触发器

-6.4 数据库游标

--6.4 数据库游标

-6.5 嵌入式SQL编程

--6.5 嵌入式SQL编程

-第6章 数据库应用编程--本章单元测试

-第6章 数据库应用编程--重点问题讨论

第7章 NoSQL数据库技术

-7.1 NoSQL数据库概述

--7.1.1 NoSQL数据库概述-1

--7.1.2 NoSQL数据库概述-2

--7.1.3 NoSQL数据库概述-3

-7.2 列存储数据库

--7.2.1列存储数据库-1

--7.2.2列存储数据库-2

-7.3 键值对数据库

--7.3.1 键值对数据库-1

--7.3.2 键值对数据库-2

--7.3.3 键值对数据库-3

-7.4 文档型数据库

--7.4.1文档型数据库-1

--7.4.2文档型数据库-2

--7.4.3文档型数据库-3

-7.5 图形数据库

--7.5.1图形数据库-1

--7.5.2图形数据库-2

--7.5.3 图形数据库-3

-7.6 HBase数据库项目实践

--7.6 HBase数据库项目实践

-第7章 NoSQL数据库技术--本章单元测试

-第7章 NoSQL数据库技术--本章重点问题讨论

期末考试

-期末测试--期末测试

6.2 数据库存储过程笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。