前言

简单整理一下存储过程。

正文

需要MySQL 5 MySQL 5添加了对存储过程的支持,因此,本章内容适用于MySQL 5及以后的版本。

迄今为止,使用的大多数SQL语句都是针对一个或多个表的单条语句。

并非所有操作都这么简单,经常会有一个完整的操作需要多条语句才能完成。

例如,考虑以下的情形。

  1. 为了处理订单,需要核对以保证库存中有相应的物品。

  2. 如果库存有物品,这些物品需要预定以便不将它们再卖给别的人,并且要减少可用的物品数量以反映正确的库存量。

  3. 库存中没有的物品需要订购,这需要与供应商进行某种交互。

  4. 关于哪些物品入库(并且可以立即发货)和哪些物品退订,需要通知相应的客户。

既然我们知道了什么是存储过程,那么为什么要使用它们呢?有许多理由,下面列出一些主要的理由。

  1. 通过把处理封装在容易使用的单元中,简化复杂的操作(正如前面例子所述)。

  2. 由于不要求反复建立一系列处理步骤,这保证了数据的完整性。如果所有开发人员和应用程序都使用同一(试验和测试)存储过程,则所使用的代码都是相同的。

这一点的延伸就是防止错误。需要执行的步骤越多,出错的可能性就越大。防止错误保证了数据的一致性。

  1. 简化对变动的管理。如果表名、列名或业务逻辑(或别的内容)有变化,只需要更改存储过程的代码。使用它的人员甚至不需要知道这些变化。

这一点的延伸就是安全性。通过存储过程限制对基础数据的访问减少了数据讹误(无意识的或别的原因所导致的数据讹误)的机会。

  1. 提高性能。因为使用存储过程比使用单独的SQL语句要快。

  2. 存在一些只能用在单个请求中的MySQL元素和特性,存储过程可以使用它们来编写功能更强更灵活的代码

换句话说,使用存储过程有3个主要的好处,即简单、安全、高性能。

显然,它们都很重要。不过,在将SQL代码转换为存储过程前,也必须知道它的一些缺陷。

  1. 一般来说,存储过程的编写比基本SQL语句复杂,编写存储过程需要更高的技能,更丰富的经验。

  2. 你可能没有创建存储过程的安全访问权限。许多数据库管理员限制存储过程的创建权限,允许用户使用存储过程,但不允许他们创建存储过程。

不能编写存储过程?你依然可以使用 MySQL将编写存储过程的安全和访问与执行存储过程的安全和访问区分开来。这是好事情。

即使你不能(或不想)编写自己的存储过程,也仍然可以在适当的时候执行别的存储过程。

创建存储过程

create PROCEDURE productpricing()
BEGIN
SELECT AVG(prod_price) as priceaverage
from (products);
end;

执行存储过程

call productpricing

mysql命令行客户机的分隔符 如果你使用的是mysql命令行

实用程序,应该仔细阅读此说明。

默认的MySQL语句分隔符为;(正如你已经在迄今为止所使用

的MySQL语句中所看到的那样)。mysql命令行实用程序也使

用;作为语句分隔符。如果命令行实用程序要解释存储过程自

身内的;字符,则它们最终不会成为存储过程的成分,这会使

存储过程中的SQL出现句法错误。

解决办法是临时更改命令行实用程序的语句分隔符,如下所示:

其中,DELIMITER //告诉命令行实用程序使用//作为新的语

句结束分隔符,可以看到标志存储过程结束的END定义为END

//而不是END;。这样,存储过程体内的;仍然保持不动,并且

正确地传递给数据库引擎。最后,为恢复为原来的语句分隔符,

可使用DELIMITER ;。 除\符号外,任何字符都可以用作语句分隔符。

如果你使用的是mysql命令行实用程序,在阅读本章时请记住

这里的内容。

删除存储过程

drop PROCEDURE productpricing;

参数

CREATE PROCEDURE productpricing(
out p1 DECIMAL(8,2),
out p2 DECIMAL(8,2),
out p3 DECIMAL(8,2))
BEGIN
SELECT MIN(prod_price) INTO p1
FROM products;
SELECT MAX(prod_price) INTO p2
FROM products;
SELECT AVG(prod_price) INTO p3
FROM products;
END;

这种参数可以为我们输出值。

CALL productpricing(@pricelow,@pricelow,@priceaverage)

这样是没有返回结果的。

看到受影响的结果为一行。

select @pricelow,@pricelow,@priceaverage

这样就有返回结果了。

再举一个in 和out的例子。

create PROCEDURE ordertotal(in onumber INT,
OUT ototal DECIMAL(8,2)
)
BEGIN
SELECT SUM(item_price*quantity)
FROM orderitems
WHERE order_num=onumber
INTO ototal;
END

调用:

CALL ordertotal(20005,@total)

查询:

SELECT @total

迄今为止使用的所有存储过程基本上都是封装MySQL简单的SELECT语句。

虽然它们全都是有效的存储过程例子,但它们所能完成的工作你直接用这些被封装的语句就能完成(如果说它们还能带来更多的东西,那就是使事情更复杂)。

只有在存储过程内包含业务规则和智能处理时,它们的威力才真正显现出来。

考虑这个场景。你需要获得与以前一样的订单合计,但需要对合计增加营业税,不过只针对某些顾客(或许是你所在州中那些顾客)。

那么,你需要做下面几件事情:

  1. 获得合计(与以前一样);

  2. 把营业税有条件地添加到合计;

  3. 返回合计(带或不带税)。

存储过程的完整工作如下:

-- name:ordertotal
-- parameters:onumber = order number
-- taxable = 0 if not taxable,1 if taxable
-- ototal = order total variable
create PROCEDURE ordertotal(
IN onumber INT,
IN taxable Boolean,
OUT ototal DECIMAL(8,2)
) COMMENT "obtain order total, optionally add tax"
BEGIN
-- DECLARE variable for total
DECLARE total DECIMAL(8,2);
-- DECLARE tax percentage
DECLARE taxrate INT DEFAULT 6;
-- Get the order total
SELECT SUM(item_price*quantity)
from orderitems
WHERE order_num = onumber
INTO total;
-- is this taxable?
IF taxable THEN
-- yes, so add taxrate to the total
SELECT total + (total/100*taxrate) INTO total;
END IF;
-- And finally, save to out variable
select total into ototal;
END

此存储过程有很大的变动。首先,增加了注释(前面放置--)。

在存储过程复杂性增加时,这样做特别重要。添加了另外一个参数taxable,它是一个布尔值(如果要增加税则为真,否则为假)。

在存储过程体中,用DECLARE语句定义了两个局部变量。

DECLARE要求指定变量名和数据类型,它也支持可选的默认值(这个例子中的taxrate的默认被设置为6%)。

SELECT语句已经改变,因此其结果存储到total(局部变量)而不是ototal。

IF语句检查taxable是否为真,如果为真,则用另一SELECT语句增加营业税到局部变量total。

最后,用另一SELECT语句将total(它增加或许不增加营业税)保存到ototal。

COMMENT关键字 本例子中的存储过程在CREATE PROCEDURE语
句中包含了一个COMMENT值。它不是必需的,但如果给出,将
在SHOW PROCEDURE STATUS的结果中显示。

执行:

IF语句 这个例子给出了MySQL的IF语句的基本用法。IF语句还支持ELSEIF和ELSE子句(前者还使用THEN子句,后者不使用)。

为显示用来创建一个存储过程的CREATE语句,使用SHOW CREATE PROCEDURE语句:

show CREATE PROCEDURE ordertotal;

下一节简单介绍一下游标。

mysql 必知必会整理—存储过程[十三]的更多相关文章

  1. 《MySQL必知必会》整理

    目录 第1章 了解数据库 1.1 数据库基础 1.1.1 什么是数据库 1.1.2 表 1.1.3 列和数据类型 1.1.4 行 1.1.5 主键 1.2 什么是SQL 第2章 MySQL简介 2.1 ...

  2. 《mysql必知必会》读书笔记--存储过程的使用

    以前对mysql的认识与应用只是停留在增删改查的阶段,最近正好在学习mysql相关内容,看了一本书叫做<MySQL必知必会>,看了之后对MySQL的高级用法有了一定的了解.以下内容只当读书 ...

  3. MySQL必知必会(第4版)整理笔记

    参考书籍: BookName:<SQL必知必会(第4版)> BookName:<Mysql必知必会(第4版)> Author: Ben Forta 说明:本书学习笔记 1.了解 ...

  4. 《MySQL必知必会》学习笔记整理

    简介 此笔记只包含<MySQL必知必会>中部分章节的整理笔记.这部分章节主要是一些在<SQL必知必会>中并未讲解的独属于 MySQL 数据库的一些特性,如正则表达式.全文本搜索 ...

  5. 《MySQL 必知必会》读书总结

    这是 <MySQL 必知必会> 的读书总结.也是自己整理的常用操作的参考手册. 使用 MySQL 连接到 MySQL shell>mysql -u root -p Enter pas ...

  6. 《MySQL必知必会》[01] 基本查询

    <MySQL必知必会>(点击查看详情) 1.写在前面的话 这本书是一本MySQL的经典入门书籍,小小的一本,也受到众多网友推荐.之前自己学习的时候是啃的清华大学出版社的计算机系列教材< ...

  7. mysql必知必会

    春节放假没事,找了本电子书mysql必知必会敲了下.用的工具是有道笔记的markdown文档类型. 下面是根据大纲已经敲完的章节,可复制到有道笔记的查看,更美观. # 第一章 了解SQL## 什么是S ...

  8. MySQL使用和操作总结(《MySQL必知必会》读书笔记)

    简介 MySQL是一种DBMS,即它是一种数据库软件.DBMS可分为两类:一类是基于共享文件系统的DBMS,另一类是基于客户机——服务器的DBMS.前者用于桌面用途,通常不用于高端或更关键应用. My ...

  9. mysql 必知必会总结

    以前 mysql 用的不是很多, 2 天看了一遍 mysql 必知必会又复习了一下基础.  200 页的书,很快就能看完, 大部分知识比较基础, 但还是了解了一些以前不知道的知识点.自己做一个备份,随 ...

  10. 读《MySql必知必会》笔记

    MySql必知必会 2017-12-21 意义:记录个人不注意的,或不明确的,或不知道的细节方法技巧,此书250页 登陆: mysql -u root-p -h myserver -P 9999 SH ...

随机推荐

  1. C++ //类模板分文件编写问题及解决 //第一中解决方式 直接包含源文件 //第二种解决方法 将.h 和 cpp的内容写到一起,将后缀改为.hpp文件

    1 //第一种方式被注释 2 //未被注释是第二种方式 3 //类模板分文件编写问题及解决 4 5 6 #include <iostream> 7 #include <string& ...

  2. Vue3音乐播放器组件,可显示歌词

    在线体验地址 音乐播放器 1,安装 npm install apple-music-player 或 yarn add apple-music-player 2,在main.ts中引入 import ...

  3. 调试分析 Linux 0.00 多任务切换

    当执行完 system_interrupt 函数,执行 153 行 iret 时,记录栈的变化情况. 任务0在刚进入system_interrupt函数时(调用中断int 0x80处理程序),栈空间为 ...

  4. aardio调用c语言dll动态库传结构体详细教程

    开发日记3.11 此篇用于记录发那科数控机床(Fanuc CNC)采集程序开发中,C语言写底层然后用aardio写窗口调用dll的摸索出来的类型对应和踩坑整理. 由于发那科提供的开发套件是C语言的,所 ...

  5. 利用Nginx正向代理实现局域网电脑访问外网

    引言 在网络环境中,有时候我们需要让局域网内的电脑访问外网,但是由于网络策略或其他原因,直接访问外网是不可行的.这时候,可以借助 Nginx 来搭建一个正向代理服务器,实现局域网内电脑通过 Nginx ...

  6. go-view 依赖库

    go-view 依赖库 打包es5 由于当前node版本是 16.18 最新版本的不支持,所以装个老版的 npm install @vitejs/plugin-legacy@4.0.4 --save- ...

  7. iview Button按钮 全局click事件vue拦截 节流 - 防抖 Throttle debounce

    这里是按钮的节流,就没用防抖 const setVueClickGlobalThrottle = Vue => { // 节流 const on = Vue.prototype.$on Vue. ...

  8. react 修改页面title - react-document-title

    安装 cnpm install --save react-document-title 引用 import DocumentTitle from 'react-document-title' 代码 & ...

  9. 基于bes2300 的六轴传感器mpu6050调试总结

    需求  在医疗健康领域,有很多场景需要分析佩戴者的姿势和动作.mpu6050多轴传感器是一个不二的选择.假如想把功耗做的低一些,放在耳机里,bes2300芯片配合mpu6050是一个不错的选择.遗憾的 ...

  10. MySQL 如何以当前日期时间作为字段初始默认值?

    1.以当前时间作为默认值 使用 DEFAULT CURRENT_TIMESTAMP 声明字段,插入记录时不用指定 dt,自动置入当前时间 CREATE TABLE t1 ( dt DATETIME D ...