Cursor

2023-11-07

Mac安装使用Mysql教程(从零开始)

第十二章 游标

12.1 游标简介

       游标(cursor)可以在SQL检索结果集中前进或后退一行或多行。游标是存储在DBMS服务器上的数据库查询,它不是一条SELECT语句,而是该语句检索出来的结果集。在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据。
       不同的DBMS支持不同的游标选项和特性。常见的游标选项及特性如下所示:

  • 能够标记游标为只读,使数据能读取,但不能更新和删除。

  • 能控制可以执行的定向操作(向前、向后、第一、最后、绝对位置、相对位置等)。

  • 能标记某些列为可编辑的,某些列为不可编辑的。

  • 规定范围,使游标对创建它的特定请求(如存储过程)或对所有请求可访问。

  • 指示 DBMS 对检索出的数据(而不是指出表中活动数据)进行复制,使数据在游标打开和访问期间不变化。

    注意
    Microsoft Access不支持游标,MySQL5以前的MySQL不支持游标,SQLite支持的游标称为步骤(step),它们的基本概念相同,但语法不同。
    Web 应用开发不适合使用 游标,要根据自己的需要重新开发相应的功能。

12.2 游标使用

       使用游标包含如下几个明确步骤:

  • MySQL游标只能用于存储过程(和函数)。
  • 在使用游标前,必须声明(定义)它。这个过程实际上没有检索数据, 它只是定义要使用的 SELECT 语句和游标选项。
  • 一旦声明,就必须打开游标以供使用。这个过程用前面定义的 SELECT 语句把数据实际检索出来。
  • 对于填有数据的游标,根据需要取出(检索)各行。
  • 在结束游标使用时,必须关闭游标,可能的话,释放游标(有赖于具体的 DBMS)。

       上述游标使用步骤的介绍可能比较抽象,通过以下三个实例会有更好的理解。

  • 实例一
           游标最基本用法为根据需要自行获取数据表的某几行,本实例中的游标用于存储无邮件地址的顾客的编号,名字,地址和联系方式。本实例中对游标的使用是获取其前三行的数据并存入变量中(这一操作利用SELECT语句是无法实现的)。
    1. 创建存储过程
      mysql> DELIMITER
      mysql> CREATE PROCEDURE build_email_list_1 ()
                > BEGIN
    2. 声明游标中需使用的变量
      游标声明必须在变量声明之后,否则会报错。
                > DECLARE c_id char(10) DEFAULT “”;            – cust_id
                > DECLARE c_name char(50) DEFAULT “”;      – cust_name
                > DECLARE c_address char(50) DEFAULT “”;   – cust_address
                > DECLARE c_contact char(50) DEFAULT “”;    – cust_contact
    3. 创建游标
      需说明游标对应的表及过滤条件
                > DEClARE CustCursor CURSOR FOR SELECT cust_id, cust_name, cust_address, cust_contact FROM Customers WHERE cust_email IS NULL;
    4. 打开游标
                > OPEN CustCursor;
    5. 访问游标数据
      使用FETCH访问游标数据,一次只能访问一行,要获取前三行数据需执行三次 FETCH
                > FETCH CustCursor INTO c_id, c_name, c_address, c_contact;
                > SELECT c_id, c_name, c_address, c_contact;
                > FETCH CustCursor INTO c_id, c_name, c_address, c_contact;
                > SELECT c_id, c_name, c_address, c_contact;
                > FETCH CustCursor INTO c_id, c_name, c_address, c_contact;
                > SELECT c_id, c_name, c_address, c_contact;
    6. 关闭游标
                > CLOSE CustCursor;
    7. 结束存储过程
                > END//
    8. 测试结果
      mysql> DELIMITER ;
      mysql> CALL build_email_list_1();
      ±-----------±-----------±---------------------±---------------+
      | c_id | c_name | c_address | c_contact |
      ±-----------±-----------±---------------------±---------------+
      | 1000000002 | Kids Place | 333 South Lake Drive | Michelle Green |
      ±-----------±-----------±---------------------±---------------+
      1 row in set (0.00 sec)
      ±-----------±---------±-------------±----------+
      | c_id | c_name | c_address | c_contact |
      ±-----------±---------±-------------±----------+
      | 1000000007 | LOL Land | 123 Toc Road | NULL |
      ±-----------±---------±-------------±----------+
      1 row in set (0.00 sec)
      ±-----------±--------±---------------±----------+
      | c_id | c_name | c_address | c_contact |
      ±-----------±--------±---------------±----------+
      | 1000000008 | CF Land | 321 Tic Avenue | NULL |
      ±-----------±--------±---------------±----------+
      1 row in set (0.00 sec)
      Query OK, 0 rows affected (0.00 sec)
  • 实例二
           实例一中的 F~ETCH 代码重复了三次,可以使用循环避免重复输入相同的代码。本实例中对游标的使用是获取游标中的所有数据,并将数据存入变量中。
    1. 创建存储过程
      mysql> DELIMITER
      mysql> CREATE PROCEDURE build_email_list_2 ()
                > BEGIN
    2. 声明游标中需使用的变量
      游标声明必须在变量声明之后,否则会报错。变量 c_finished 表示结束循环的变量。
                > DECLARE c_id char(10) DEFAULT “”;            – cust_id
                > DECLARE c_name char(50) DEFAULT “”;      – cust_name
                > DECLARE c_address char(50) DEFAULT “”;   – cust_address
                > DECLARE c_contact char(50) DEFAULT “”;    – cust_contact
                >DECLARE c_finished INTEGER DEFAULT 0;
    3. 创建游标
      需说明游标对应的表及过滤条件
                > DEClARE CustCursor CURSOR FOR SELECT cust_id, cust_name, cust_address, cust_contact FROM Customers WHERE cust_email IS NULL;
    4. 声明异常处理handler
      当获取不到下一语句时,设置c_finished为1,然后触发退出动作
               > DECLARE EXIT HANDLER FOR NOT FOUND SET c_finished = 1;
    5. 打开游标
                > OPEN CustCursor;
    6. 访问游标数据
      利用循环访问游标数据,当找不到数据时退出循环。
                >get_email: LOOP
                > FETCH CustCursor INTO c_id, c_name, c_address, c_contact;
                > SELECT c_id, c_name, c_address, c_contact;
                > IF c_finished = 1 THEN LEAVE get_email;
                > END IF;
                > END LOOP get_email;
    7. 关闭游标
                > CLOSE CustCursor;
    8. 结束存储过程
                > END//
    9. 测试结果
      mysql> DELIMITER ;
      mysql> CALL build_email_list_2();
      ±-----------±-----------±---------------------±---------------+
      | c_id | c_name | c_address| c_contact |
      ±-----------±-----------±---------------------±---------------+
      | 1000000002 | Kids Place | 333 South Lake Drive | Michelle Green |
      ±-----------±-----------±---------------------±---------------+
      1 row in set (0.00 sec)
      ±-----------±---------±-------------±----------+
      | c_id | c_name | c_address | c_contact |
      ±-----------±---------±-------------±----------+
      | 1000000007 | LOL Land | 123 Toc Road | NULL |
      ±-----------±---------±-------------±----------+
      1 row in set (0.00 sec)
      ±-----------±--------±---------------±----------+
      | c_id | c_name | c_address | c_contact |
      ±-----------±--------±---------------±----------+
      | 1000000008 | CF Land | 321 Tic Avenue | NULL |
      ±-----------±--------±---------------±----------+
      1 row in set (0.00 sec)
      ±-----------±-------±--------------±----------+
      | c_id | c_name | c_address | c_contact |
      ±-----------±-------±--------------±----------+
      | 1000000009 | PAPP | 200 Fake Lane | NULL |
      ±-----------±-------±--------------±----------+
      1 row in set (0.00 sec)
      ±-----------±-------±---------------±----------+
      | c_id | c_name | c_address | c_contact |
      ±-----------±-------±---------------±----------+
      | 1000000010 | PAPAPA | 250 Faker Road | NULL |
      ±-----------±-------±---------------±----------+
      1 row in set (0.00 sec)
      Query OK, 0 rows affected (0.00 sec)
  • 实例三
           实例二中的数据分五次进行显示,可以将数据插入表中并一次性显示出来。本实例中对游标的使用是获取游标中的所有数据,并将数据存入表格 Null_email 中
    1. 创建存储过程
      mysql> DELIMITER
      mysql> CREATE PROCEDURE build_email_list_3 ()
                > BEGIN
    2. 声明游标中需使用的变量
      游标声明必须在变量声明之后,否则会报错。变量 c_finished 表示结束循环的变量。
                > DECLARE c_id_v char(10) DEFAULT “”;            – cust_id
                > DECLARE c_name_v char(50) DEFAULT “”;      – cust_name
                > DECLARE c_address_v char(50) DEFAULT “”;   – cust_address
                > DECLARE c_contact_v char(50) DEFAULT “”;    – cust_contact
                >DECLARE c_finished INTEGER DEFAULT 0;
    3. 创建游标
      需说明游标对应的表及过滤条件
                > DEClARE CustCursor CURSOR FOR SELECT cust_id, cust_name, cust_address, cust_contact FROM Customers WHERE cust_email IS NULL;
    4. 声明异常处理handler
      当获取不到下一语句时,设置c_finished为1,然后触发退出动作。创建一个用于存储数据的表
                > DECLARE EXIT HANDLER FOR NOT FOUND SET c_finished = 1;
                > CREATE TABLE IF NOT EXISTS Null_email(c_id char(10), c_name char(50), c_address char(50), c_contact char(50))
    5. 打开游标
                > OPEN CustCursor;
    6. 访问游标数据
      利用循环访问游标数据,当找不到数据时退出循环。
                >get_email: LOOP
                > FETCH CustCursor INTO c_id_v, c_name_v, c_address_v, c_contact_v;
                > INSERT INTO Null_email(c_id, c_name, c_address, c_contact) VALUES (c_id_v, c_name_v, c_address_v, c_contact_v);
                > IF c_finished = 1 THEN LEAVE get_email;
                > END IF;
                > END LOOP get_email;
    7. 关闭游标
                > CLOSE CustCursor;
    8. 结束存储过程
                > END//
    9. 测试结果
      mysql> DELIMITER ;
      mysql> CALL build_email_list_2();
      mysql> select * from Null_email;
      ±-----------±-----------±---------------------±---------------+
      | c_id | c_name | c_address | c_contact |
      ±-----------±-----------±---------------------±---------------+
      | 1000000002 | Kids Place | 333 South Lake Drive | Michelle Green |
      | 1000000007 | LOL Land | 123 Toc Road | NULL |
      | 1000000008 | CF Land | 321 Tic Avenue | NULL |
      | 1000000009 | PAPP | 200 Fake Lane | NULL |
      | 1000000010 | PAPAPA | 250 Faker Road | NULL |
      ±-----------±-----------±---------------------±---------------+
      5 rows in set (0.00 sec)

    注意
            由MySQL官方手册可知,声明游标需在声明异常处理handler之前,声明变量和条件之后。而经过个人实践得知,声明游标需在创建表格之前。

12.3 参考

[1] Ben Forta.SQL必知必会-中文-第4版
[2] Cursors官方指南

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Cursor 的相关文章

  • 当数据表输入来自服务器的 JSON 数据时,更改 Google 图表栏颜色

    我一直在努力使用谷歌图表 API 我在 SO 上发现了这个出色的例子PHP MySQL Google Chart JSON 完整示例 https stackoverflow com questions 12994282 php mysql
  • 在 MySQL 数据库中存储图像文件或 URL?哪个更好? [复制]

    这个问题在这里已经有答案了 可能的重复 在数据库中存储图像 是还是否 https stackoverflow com questions 3748 storing images in db yea or nay 数据库中的图像与文件系统中的
  • SQL 检查一组日期是否在指定的日期范围内

    我有一个表 其中保存架构中房间不可用的日期 ROOM ID DATE UNAVAILABLE 我需要一个 sql 查询来检查两个日期范围内是否有可用房间 类似于 Select All rooms that are constantly av
  • MYSQL中收盘价的简单移动平均线计算和更新表

    我可以使用一些帮助 最好是虚拟指南 来更新下表 CREATE TABLE SYMBOL day date NOT NULL open decimal 8 3 DEFAULT NULL high decimal 8 3 DEFAULT NUL
  • Codeigniter 加入多个条件

    我正在使用 Codeigniter Active Records 课程 我想加入我的users与我的桌子clients表 这样我就可以显示用户的 真实 姓名 而不仅仅是他们的 ID 这是什么clients表看起来像 示例 列 a 1 a 2
  • Preg_replace() 删除除查询结尾之外的所有内容

    首先 为我糟糕的英语感到抱歉 我有这样的疑问 SELECT t1 SELECT COUNT FROM table a t2 WHERE t1 id t2 id c AND t2 status 1 AS aula FROM table c t
  • MySQL 按主键排序

    某些 SQL 服务器允许使用通用语句 例如ORDER BY PRIMARY KEY 我不相信这适用于 MySQL 是否有任何此类解决方法可以允许跨多个表自动选择 或者是否需要查找查询来确定主键 我一直在研究的解决方法包括调用SHOW COL
  • PHP PDO相关:更新SQL语句未更新数据库内容

    我正在尝试使用准备好的语句来实现更新语句PHP http en wikipedia org wiki PHP脚本 但它似乎没有更新数据库中的记录 我不确定为什么 所以如果您能分享一些见解 我将不胜感激 Code query UPDATE D
  • 如何以最少的查询次数获取帖子列表和关联标签

    我的表格结构如下 标签 更多的是一个类别 id 标签名称 描述 slug POSTS ID 标题 网址 邮戳 id idPost idTag USERS ID 用户名 userSlug VOTES id idPost idUser 每个帖子
  • 社交应用程序的数据库设计和优化注意事项

    通常的情况 我有一个简单的应用程序 允许人们上传照片并关注其他人 因此 每个用户都会有类似 墙 或 活动源 的东西 他或她可以在其中看到他 她的朋友 他或她关注的人 上传的最新照片 大多数功能都很容易实现 然而 当涉及到这个历史活动源时 由
  • MySql 最后插入 ID,连接器 .net

    我正在使用 MySql Connector net 我需要获取最后一个查询生成的插入 id 现在 我假设返回值是MySqlHelper ExecuteNonQuery应该是最后一个插入id 但它只返回1 我正在使用的代码是 int inse
  • Mysql innoDB 不断崩溃[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我的数据库 mysql 服务器不断崩溃 重新启动 我不知道该怎么办 我不断在 dbname org err 文件中收到以下内容 13120
  • 使 pdo::query 静态

    当我运行下面的代码时出现此错误 我通常使用 msql 函数 但我尝试使用 PDO 代替 怎么了 致命错误 第 14 行无法静态调用非静态方法 PDO query
  • Python:如何使用生成器来避免 sql 内存问题

    我有以下方法来访问 mysql 数据库 并且查询在服务器中执行 我无权更改有关增加内存的任何内容 我对生成器很陌生 并开始阅读更多有关它的内容 并认为我可以将其转换为使用生成器 def getUNames self globalUserQu
  • 查询中列的顺序重要吗?

    当从 MySQL 表中选择列时 与表中的顺序相比 选择列的顺序是否会影响性能 不考虑可能覆盖列的索引 例如 您有一个包含行 uid name bday 的表 并且有以下查询 SELECT uid name bday FROM table M
  • MySQL Connector/C++ 库链接错误问题

    PROBLEM 好吧 我一直在尝试遵循 MySQL Forge Wiki 和其他一些网站上的示例代码 这些网站提供了有关如何获得简单数据库连接的教程 但由于某种原因 我的项目总是因链接错误而失败 我可以我自己不明白为什么或如何解决它 我仍在
  • 如何正确转义mysql?

    我刚刚发现如果我写 select from tbl where name like foo 然后添加 foo 作为参数及其值 a 用户数据 它不会正确转义 我勒个去 它想要 a 即使我使用参数 我还是忍不住觉得我对 sql 注入持开放态度
  • 为什么我的 if 语句没有按我预期的方式工作?

    我正在尝试实现以下目标 我向我的 SQL 数据库询问使用SELECT FROM subjects 这样做之后我要求使用数组mysqli fetch assoc 在那之前一切都很好 现在的问题是 当我尝试在每个循环中修改 genero 的值
  • 如何在Sequelize中设置查询超时?

    我想看看如何在 Sequelize 中设置查询的超时时间 我查看了 Sequelize 文档以获取一些信息 但我找不到我要找的东西 我发现的最接近的是 pools acquire 选项 但我不想设置传入连接的超时 而是设置正在进行的查询的超
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri

随机推荐

  • 安卓开发日志捕获,错误日志捕获catch,崩溃日志捕获,抓取崩溃日志

    import android content Context import android content SharedPreferences import android content pm PackageInfo import and
  • 从街边小吃到网上爆款,螺蛳粉是如何逆袭走红的呢?

    要说现当下最火的食物是什么 那螺蛳粉肯定占有一席之地 喝奶茶已经不是当下年轻人的续命方式了 现在只有会嗦粉的才能称得上是整条街最靓的崽 在今年五花八门的热搜中 可以说螺蛳粉长在了热搜上 从西瓜微数热搜榜来看 关于螺蛳粉的热搜可是数不胜数 在
  • windows系统升级node

    直接去官网下载对应版本的安装包 覆盖到原来的下载路径就可以了 注意一定要下载稳定版本的下载 Node js nodejs org https nodejs org zh cn download 查看node下载路径where node 查看
  • 线程池基础入门

    文章目录 线程池的状态 ThreadPoolExecutor 构造方法 Executors 固定大小的线程池 Executors 定时线程池 Executors 带缓冲线程池 Executors 单线程线程池 线程池常用方法 线程池的状态
  • 对接阿里云弹性收缩小结

    1 垂直伸缩 执行垂直伸缩任务时 系统自动完成停止目标实例 调整实例规格 启动目标实例一系列操作 这个相对简单 直接增加实例配置 2 弹性伸缩 参考 阿里云弹性伸缩初体验 偶影独行的博客 CSDN博客 Sina Visitor System
  • Android电池信息

    Android中电池信息 Battery information 的取得 这里介绍电池信息的取得 Android content BroadcastReceiver类 Android os BatteryManager类 电池信息的取得 调
  • Jenkins连接k8s的多种姿势

    目录 1 概述 2 同集群 3 跨集群 3 1 端口有什么 3 2 网络策略打通 3 3 证书的生成和配置 3 4 配置连接外部的 k8s 集群 4 测试验证 4 1 配置 pod template 4 2 自由风格构建测试 4 3 流水线
  • Vue计算属性实现及简写

    计算属性 1 定义 要用的属性不存在 要通过已有的属性计算得来 2 原理 底层借助了Object defineproperty方法提供的getter和setter 3 get函数什么时候执行 1 初次读取时会执行一次 2 当依赖的数据发生改
  • 博客网址

    博客不在更新 转到www fulus wang 转载于 https my oschina net fuluS blog 713434
  • pandas整表写入excel指定位置_pandas处理excel的常用方法技巧(上)

    1 导库 import pandas as pd 2 读取excel文件 这里要注意的就是第二个参数header如果不设置 pandas会默认把excel的第一行当作columns header None的时候pandas会为我们新生成从0
  • 使用深度学习模型CNN进行实时情绪检测研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现 1 概述 使用深度学习模型CNN进行实时情绪检测是一
  • 字符串、字符数组的截取函数:strncpy、strsub

    字符数组的截取函数 字符串截取函数
  • 【材质和贴图】

    1 贴图坐标的换算公式 a1 a0 Offset 1 Tilling
  • C语言——每日一题

    1 倒置字符串 倒置字符串 要将每一个单词逆序输出 首先可以将整个字符串内容都逆序输出 然后再将字符串中的每一个单词再进行逆序 例如 逆序 i like beijing 先逆序成 gnijieb ekil i 再将每个单词逆序 beijin
  • 用ram实现寄存器堆_51单片机RAM数据存储区学习笔记

    1 RAM keil C语言编程 RAM是程序运行中存放随机变量的数据空间 在keil中编写程序 如果当前模式为small模式 如果总的变量大小未超过128B 则未初始化的变量的初值默认为0 如果所有的变量超过单片机small模式下的128
  • 基于Tensorflow来重现GPT v1模型

    OpenAI推出的ChatGPT模型让我们看到了通用人工智能的发展潜力 我也找了GPT的相关论文来进行研究 OpenAI在2017年的论文Improving Language Understanding by Generative Pre
  • 线程创建的三种方式

    1 Thread类实现多线程 步骤 1 创建一个Thread线程类的子类 重新run方法 2 创建该子类的实例 通过调用start方法启动线程 示例 class MyThread extends Thread public MyThread
  • c/c++语言的几个关键字

    1 register 中文意思为 寄存器 由来 在C语言中的register修饰的变量表示将此变量存储在CPU的寄存器中 由于CPU访问寄存器比访问内存快很多 可以大大提高运算速度 注意事项 1 用register修饰的变量只能是局部变量
  • 打造你的专属印章(c语言)

    制作原理 我们看到屏幕上显示的汉字的字型有两种表达方式 一种称为矢量方式 一种称为点阵方式 其中的点阵方式较为简单 其原理就是好比 铺地砖 有的铺为白色 有的铺为黑色 只要精心安排 就会组成我们希望的图案 当然也可以是汉字 瓷砖越多 铺出的
  • Cursor

    Mac安装使用Mysql教程 从零开始 第一章 Mac安装MySQL 1 1 过程记录 1 2 参考 第二章 安装数据库管理软件DBeaver 2 1 过程记录 2 2 参考 第三章 DBeaver创建MySQL数据库 3 1 过程记录 3