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 的相关文章

  • 为什么 peewee 将“id”列包含到 mysql select 查询中?

    我正在尝试学习如何将 peewee 与 mysql 一起使用 我在 mysql 服务器上有一个现有数据库和一个现有表 该表当前为空 我现在正在测试 gt gt gt db MySQLDatabase nhl user root passwd
  • 如何限制登录尝试 - PHP & MySQL & CodeIgniter

    我希望能够根据失败的尝试来限制登录尝试 但我有一些问题 我应该使用 MySQL 吗 读到它可能会给数据库带来压力 我应该在每个用户和系统范围内进行限制还是仅在系统范围内进行限制 这样可以防止普通人猜测密码 我应该如何计算我的阈值 因此它会自
  • 防止同一用户在桌面应用程序上登录

    我正在开发一个多用户桌面应用程序 我需要找到一种方法 让每个用户名一次只允许一个用户登录 基本上 John 无法从 PC A 登录应用程序 然后再运行到 PC B 并登录 我的想法是设置一个位标志来指示用户已登录 并且当从另一个位置进行尝试
  • 添加新数据源(mysql)wildfly

    我正在尝试将新的数据源 mysql jdbc 驱动程序添加到我的 Wildfly 服务器 我创建了文件夹 wildfly x x x modules system layers base com mysql main 我这里有 jdbc j
  • 您可以使用 CASE WHEN THEN 别名进行 GROUP BY 吗?

    我有一个从别名为 Length 的 CASE WHEN THEN 状态 或者可以使用多个 IF 语句 计算的 SELECT 语句 并且我需要将结果正确地分组在一起 SELECT 似乎有效 但该小组将它们分组错误 这是我的声明 SELECT
  • PHP:如何使浏览器点击下载文件

    PHP 初学者 文件上传成功 但我的浏览器不下载文件 而是读取文件 所以我参考了其他线程并发现下面的代码不起作用 我想在单击超链接时下载文件download 从MySQL数据库中选择路径 rows mysqli num rows resul
  • 表'/tmp/#sql_18b4_0.MYI'的密钥文件不正确;尝试修复它

    我从我们的开发人员那里收到一个查询 该查询未在服务器上执行并给出以下错误 Incorrect key file for table tmp sql 18b4 0 MYI try to repair it 我已经单独检查了所有表及其索引 所有
  • 将 MySQL 查询的输出转换为 utf8

    我的数据库中有一个表 我想运行如下查询 SELECT column1 column2 FROM my table WHERE my condition 但我希望 mysql 返回column2以utf8编码 mysql中有什么函数可以完成这
  • 将结果行强制转换为对象

    有没有办法将调用存储过程获得的结果行强制转换为特定对象 以便我可以仅将该对象的列表传递到视图中 我知道我可以使用 Node list 之类的东西来做到这一点 但我最终将用一个相当复杂的存储过程替换 getnodes 该存储过程创建临时表并执
  • Hibernate不生成级联

    我有一套hibernate hbm2ddl auto创建以便 Hibernate 为我在 mysql 中创建表 但是 休眠似乎没有正确添加Cascade关于表中的参考文献 然而 当我删除一行 并且我有一个删除级联作为休眠注释时 它确实有效
  • MySQL 错误:#1142 - SELECT 命令被拒绝给用户

    我在一台服务器上的某个查询时遇到问题 在我测试过的所有其他地方 它工作得很好 但在我想使用它的服务器上 它不起作用 这是关于以下 SQL SELECT facturen id AS fid projecten id AS pid titel
  • SQLAlchemy Join 从多个表中检索数据

    我正在尝试从多个表中检索数据SQL炼金术使用 join 方法 当我运行查询时 我希望得到一个对象 该对象包含来自不同表的所有数据 以便我可以使用a 区域名称等等在哪里区域名称位于其中一张连接的表上 下面是我正在运行的查询和表布局 如果有人能
  • 注意:php中数组到字符串的转换

  • 在 SQL 查询中使用聚合函数

    我的表结构是这样的 ATT Table Fields Act ID Assigned To ID Percent Complete Integer value Act ID is primary key Assigned To ID is
  • sql 查询不适用于 order by

    这是我原来有效的查询 Select FROM story st sentences s speaker sp WHERE st lesson id 1 AND st speaker id sp speaker id AND st sente
  • AWS RDS 如何设置 MySQL 数据库

    我有一个 Java 应用程序成功运行在Amazon Web Services Elastic Beanstalk 我正在尝试设置MySQL 我已经创建了一个数据库实例 如您所见 问题一 如何将我的 Java 应用程序连接到数据库 我有以下代
  • 致命错误:无法在functions.php第25行中重新声明session_start()

    当我尝试让登录部分正常工作时遇到问题 我不断遇到的问题是 致命错误 无法在 public html login functions php 第 25 行重新声明 session start
  • 按任意顺序对 SQL 行输出进行排序?

    因此 在我的数据库中 我存储乐器名称 以及各种其他属性 比方说id是主键 并且name是唯一的密钥 在 PHP 脚本中 我按仪器类别选择项目 如下所示 name mysql real escape string POST name row
  • mysql 部分索引、反向索引

    我有一张包含单词列表的表格 字 VARCHAR 16 我需要创建一个反向索引 IE 单词 apple 将索引为 elppa 单词 banana 将索引为 ananab 依此类推 另外 是否可以索引单词的一部分 例如 跳过第一个 最后一个或
  • 使用 mysql_real_escape_string() 时出现访问被拒绝错误

    我试图在数据进入我的数据库之前转义一些数据 但我不断收到此错误 Warning mysql real escape string Access denied for user 现在 这通常表明我尚未连接到数据库 它还声明 使用密码 NO 我

随机推荐

  • 安卓开发日志捕获,错误日志捕获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