MySQL存储过程和游标
一、存储过程
什么是存储过程,为什么要使用存储过程以及如何使用存储过程,并且介绍创建和使用存储过程的基本语法。
什么是存储过程:
存储过程可以说是一个记录集,它是由一些T-SQL语句组成的代码块,这些T-SQL语句代码像一个方法一样
实现一些功能(对单表或多表的增删改查),然后再给这个代码块取一个名字,在用到这个功能的时候调用
他就行了。
存储过程的好处:
由于数据库执行动作时,是先编译后执行的。然而存储过程是一个编译过的代码块,所以执行效率要比
T-SQL语句高。
一个存储过程在程序在网络中交互时可以替代大堆的T-SQL语句,所以也能降低网络的通信量,提高通信速率。
通过存储过程能够使没有权限的用户在控制之下间接地存取数据库,从而确保数据的安全
存储过程的基本语法:
--------------------创建存储过程------------------------------------
CREATE PROCEDURE procedure_name( IN|OUT variable data_type)
BENGIN
sql_statement;
......
END;
-- MySQL支持IN(传递给存储过程)、OUT(从存储过程传出)
-- variable 变量
-- data_type 参数的数据类型
-- sql_statement 中 INTO parameter 的把值保存到相应的变量中(通过INTO关键字)
--------------------执行存储过程------------------------------------
CALL procedure_name(@parameters);
--------------------删除存储过程------------------------------------
DROP PROCEDURE procedure_name;
-- 如果指定的过程不存在,则DROP PROCEDURE将会产生一个错误。
-- 使用DROP PROCEDURE IF EXISTS
--------------------检查存储过程------------------------------------
SHOW CREATE PROCEDURE procedure_name;
-------------------------------------------------------------------
-- 为了获得包括何时、有谁创建等详细信息的存储过程列表,使用
SHOW PROCEDURE STATUS LIKE ' ';
-- LIKE 指定过滤模式
备注:mysql命令行实用程序使用;作为语句分隔符,所以用命令行写存储过程自身内的;字符,会使存储过程的SQL出现句法错误。解决办法是临时更改命令行的语句分隔符,如下所示:
-- 更改MySQL分隔符 除\符号外,任何字符都可以用作语句分隔符。
DELIMITER //
DELIMITER ;
存储过程示例:
场景:
你需要获得与以前一样的订单合计,但需要对合计增加营业税,不过只针对某些顾客。那么,你需要做下面几件事情:
获得合计;
把营业税有条件地添加到合计;
返回合计(带或不带税)。
存储过程的完整工作如下:
-- Name: ordertotal
-- Parameters: onumber = order number
-- taxable = 0 if not taxable, 1 if taxable
-- ototal = order total variable
DROP PROCEDURE IF EXISTS ordertotal;
CREATE PROCEDURE ordertotal(
IN onumber INT,
IN taxable BOOLEAN,
OUT ototal DECIMAL(8,2)
) COMMENT 'Obtion ordertotal, optionally adding tax'
BENGIN
-- 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;
执行存储过程:
CALL ordertotal(20005, 0, @total);
SELECT @total;
CALL ordertotal(20005, 1, @total);
SELECT @total;
二、游标
什么是游标以及如何使用游标。
什么是游标:
MySQL检索操作返回一组结果集。MySQL使用简单的select语句没有办法得到第一行、下一行或前10行,也不能成批地处理它们。
游标可以从结果集中做到返回单个结果
使用游标可以轻易的取出在检索出来的行中前进或后退一行或多行的结果
游标可以遍历返回的多行结果。
补充:MySQL中游标只适用于存储过程以及函数。
使用游标步骤:
在能够使用游标前,必须声明(定义)它。这个过程实际上没有检索数据,它只是定义要使用的select语句。
一旦声明后,必须打开游标以供使用。这个过程用前面定义的select语句把数据实际检索出来。
对于有数据的游标,根据需要取出(检索)各行。
在结束游标使用时,必须关闭游标。
在声明游标后,可根据需要频繁地打开和关闭游标。在游标打开后,可根据需要频繁地执行取操作。
语法:
定义游标
DECLARE <游标名> CURSOR
FOR
select语句;打开游标
OPEN <游标名>;
使用游标
使用游标需要用关键字FETCH来取出数据,然后取出的数据需要有存放的地方,我们需要用declare声明变量存放列的数据其语法格式为:
DECLARE variable1 数据类型(与列值的数据类型相同);
FETCH [NEXT|PRIOR|FIRST|LAST] FROM <游标名> INTO [variable1,variable2,…]关闭游标
CLOSE <游标名>;
游标示例:
DROP PROCEDURE IF EXISTS processorders;
CREATE PROCEDURE processorders()
BEGIN
-- Declare local variables
DECLARE done BOOLEAN DEFAULT 0;
DECLARE o INT;
DECLARE t DECIMAL(8,2);
-- Declare the cursor
DECLARE ordernumbers CURSOR
FOR
SELECT order_num FROM orders;
-- Declare continue handler
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
-- Create a table to store the result
CREATE TABLE IF NOT EXISTS ordertotals(
id INT PRIMARY KEY AUTO_INCREMENT,
order_num INT NOT NULL,
total DECIMAL(8,2)
);
-- Open the cursor
OPEN ordertotals;
-- Loop through all rows
REPEAT
-- Get order number
FETCH ordertotals INTO o;
-- Get the total for this order
CALL ordertotal(o, 1, t);
-- Insert order and total into ordertotals
INSERT INTO ordertotals(order_num, total) VALUES(o, t);
-- End of loop
UNTIL done END REPEAT;
-- Close the cursor
CLOSE ordertotals;
END;
CALL ordertotal();
SELECT * FROM ordertotals;
三、MySQL学习脚本:
链接:https://pan.baidu.com/s/1U4HI-AC49ZUb730odAUkjw 提取码:lti7
MySQL存储过程和游标的更多相关文章
- mysql存储过程之游标遍历数据表
原文:mysql存储过程之游标遍历数据表 今天写一个mysql存储过程,根据自己的需求要遍历一个数据表,因为对存储过程用的不多,语法不甚熟悉,加之存储过程没有调试环境,花了不少时间才慢慢弄好,故留个痕 ...
- MySQL存储过程之游标实战
MySQL存储过程之游标实战 博主日前在解决一个项目需求时,没有什么好的方法,于是就来学习存储过程了,之前也是接触过,奈何年少贪玩,竟是全部又还给了大学老师-苦不堪言呐-. 先说一下业务需求吧 ...
- MariaDB MariaDB、MySQL存储过程、游标基础应用举例说明
MariaDB.MySQL存储过程.游标基础应用举例说明 by:授客 QQ:1033553122 测试环境: MariaDB-10.0.19-centos7-x86_64 实践操作: # 创建测试数据 ...
- MYSQL存储过程、游标、触发器
MySQL5 中添加了存储过程的支持. 大多数SQL语句都是针对一个或多个表的单条语句.并非所有的操作都怎么简单.经常会有一个完整的操作需要多条才能完成 存储过程简单来说,就是为以后的使用而保存的一 ...
- mysql存储过程之游标
MySQL5 中添加了存储过程的支持. 大多数SQL语句都是针对一个或多个表的单条语句.并非所有的操作都怎么简单.经常会有一个完整的操作需要多条才能完成 存储过程简单来说,就是为以后的 ...
- MYSQL学习拓展一:MySQL 存储过程之游标的使用!
一.MySQL游标的概念 游标介绍: MySQL的游标(cursor)是一个重要的概念,通过查找资料与自己的理解,主要得出以下几点关于自己的理解. 有数据缓冲的思想:游标的设计是一种数据缓冲区的思想, ...
- 解析MySQL存储过程的游标执行过程
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 内容提纲 一.测试环境搭建 二.执行过程解析 三.注意事项 一.测试环境搭建 首先创建一张表,并插入几行数据字段: CRE ...
- Mysql 存储过程使用游标
-- 完整例子 CREATE PROCEDURE test BEGIN -- 定义参数 DECLARE _id INT; -- 定义游标 DECLARE no_more_products ...
- MySQL存储过程-->通过游标遍历和异常处理迁移数据到历史表
-- 大表数据迁移,每天凌晨1点到5点执行,执行间隔时间10分钟,迁移旧数据到历史表. DELIMITER $$ USE `dbx`$$ DROP PROCEDURE IF EXISTS `pro_x ...
随机推荐
- vwmare 十月第 1 弹
step one 不管 是 ubuntu 还是 win vm tools 都是需要在虚拟的系统里面的去安装的. 这一点是相同的.
- 定义可选URL片段 定义自定义片段变量 精通ASP-NET-MVC-5-弗瑞曼
- Set,Multiset,Iterator(迭代器)详解
Set,Multiset,Iterator(迭代器) Iterator:迭代器 我们可以发现所谓一些数据结构比如说数组和链表,它们都有一些相似的性质.我们看下面两个例子: 数组:定义数组\(int~a ...
- 初学者学Java常遇到的问题,我都给你回答了!
前言 只有光头才能变强. 文本已收录至我的GitHub精选文章,欢迎Star:https://github.com/ZhongFuCheng3y/3y 春节在家刷知乎,看到了一个知乎的问题:<学 ...
- postman的简单介绍及运用
postman下载地址 https://www.getpostman.com/downloads/ postman的工作原理:发送请求给服务器,服务器处理postman发送的数据然后返回给postma ...
- RocketMQ消息模型
rocketmq采用的是发布-订阅的模式,不需要每个消费者维护自己的消息队列,生产者将消息发送到topic,消费者订阅此topic 读取消息. 基本概念: 消息模型:消息模型包括producer,co ...
- 云原生 - Istio可观察性之监控(四)
作者:justmine 头条号:大数据与云原生 微信公众号:大数据与云原生 创作不易,在满足创作共用版权协议的基础上可以转载,但请以超链接形式注明出处. 为了方便阅读,微信公众号已按分类排版,后续的文 ...
- STM32系列之新建工程模板(三)
今天,我将记录STM32如何新建一个模板步骤 第一步:首先先新建一个文件夹(英文命名的)——作为工程根目录 第二步;在文件夹中新建一个名为USER的子目录文件 第三步:点击 MDK 的菜单:Proje ...
- 【SpringBoot MQ 系列】RabbitMq 核心知识点小结
[MQ 系列]RabbitMq 核心知识点小结 以下内容,部分取材于官方教程,部分来源网络博主的分享,如有兴趣了解更多详细的知识点,可以在本文最后的文章列表中获取原地址 RabbitMQ 是一个基于 ...
- 斐波那契数列(php实现)
描述 斐波那契数列指的是这样一个数列:1.1.2.3.5.8.13.21.34... 规则 : 有N个数,第i个数的值 N(i)= N(i-1) + N(i-2) 需求: 给出下标i ,求第i 的个数 ...