SQL必知必会
陈旸
清华大学计算机博士
立即订阅
10179 人已学习
课程目录
已完结 49 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词丨SQL可能是你掌握的最有用的技能
免费
第一章:SQL语法基础篇 (19讲)
01丨了解SQL:一门半衰期很长的语言
02丨DBMS的前世今生
03丨学会用数据库的方式思考SQL是如何执行的
04丨使用DDL创建数据库&数据表时需要注意什么?
05丨检索数据:你还在SELECT * 么?
06丨数据过滤:SQL数据过滤都有哪些方法?
07丨什么是SQL函数?为什么使用SQL函数可能会带来问题?
08丨什么是SQL的聚集函数,如何利用它们汇总表的数据?
09丨子查询:子查询的种类都有哪些,如何提高子查询的性能?
10丨常用的SQL标准有哪些,在SQL92中是如何使用连接的?
11丨SQL99是如何使用连接的,与SQL92的区别是什么?
12丨视图在SQL中的作用是什么,它是怎样工作的?
13丨什么是存储过程,在实际项目中用得多么?
14丨什么是事务处理,如何使用COMMIT和ROLLBACK进行操作?
15丨初识事务隔离:隔离的级别有哪些,它们都解决了哪些异常问题?
16丨游标:当我们需要逐条处理数据时,该怎么做?
17丨如何使用Python操作MySQL?
18丨SQLAlchemy:如何使用Python ORM框架来操作MySQL?
19丨基础篇总结:如何理解查询优化、通配符以及存储过程?
第二章:SQL性能优化篇 (18讲)
20丨当我们思考数据库调优的时候,都有哪些维度可以选择?
21丨范式设计:数据表的范式有哪些,3NF指的是什么?
22丨反范式设计:3NF有什么不足,为什么有时候需要反范式设计?
23丨索引的概览:用还是不用索引,这是一个问题
24丨索引的原理:我们为什么用B+树来做索引?
25丨Hash索引的底层原理是什么?
26丨索引的使用原则:如何通过索引让SQL查询效率最大化?
27丨从数据页的角度理解B+树查询
28丨从磁盘I/O的角度理解SQL查询的成本
29丨为什么没有理想的索引?
30丨锁:悲观锁和乐观锁是什么?
31丨为什么大部分RDBMS都会支持MVCC?
32丨查询优化器是如何工作的?
33丨如何使用性能分析工具定位SQL执行慢的原因?
34丨答疑篇:关于索引以及缓冲池的一些解惑
35丨数据库主从同步的作用是什么,如何解决数据不一致问题?
36丨数据库没有备份,没有使用Binlog的情况下,如何恢复数据?
37丨SQL注入:你的SQL是如何被注入的?
第三章:认识DBMS (7讲)
38丨如何在Excel中使用SQL语言?
39丨WebSQL:如何在H5中存储一个本地数据库?
40丨SQLite:为什么微信用SQLite存储聊天记录?
41丨初识Redis:Redis为什么会这么快?
42丨如何使用Redis来实现多用户抢票问题
43丨如何使用Redis搭建玩家排行榜?
44丨DBMS篇总结和答疑:用SQLite做词云
第四章:SQL项目实战 (3讲)
45丨数据清洗:如何使用SQL对数据进行清洗?
46丨数据集成:如何对各种数据库进行集成和转换?
47丨如何利用SQL对零售数据进行分析?
结束语 (1讲)
结束语 | 互联网的下半场是数据驱动的时代
SQL必知必会
登录|注册

16丨游标:当我们需要逐条处理数据时,该怎么做?

陈旸 2019-07-17
我们在编写 SQL 语句的时候通常是面向集合进行思考,这种思考方式更让我们关注结果集的特征,而不是具体的实现过程。面向集合的思考方式与面向过程的思考方式各有特点,我们该如何理解它们呢?
我们用下面这张图开启今天的学习。这张图中一共有 9 个图形,每个图形有不同的特征,包括形状、纹理、颜色和个数等。
当我们看到这张图时,有时候会不由自主地按照某个属性进行分类,比如说按照红色分类,那么 1、4、9 就是一类。这实际上就是属于同一个条件下的查询结果集。或者我们也可以按照物体的个数来划分,比如都有 3 个物体的,那么对应的就是 2、5、6、8,这就是对应着“都包括 3 个物体”的查询结果集。
你能看出来集合思维更像是从整体的角度来考虑,然后把整个数据集按照不同的属性进行划分,形成不同的子集合。面向集合的思考方式,让我们关注“获取什么”,而不是“如何获取”,这也可以说是 SQL 与传统编程最大的区别之一,因为 SQL 本身是以关系模型和集合论为基础的。
然而也有一些情况,我们不需要对查询结果集中的所有数据行都采用相同的处理方式,需要每次处理一行或者一部分行,这时就需要面向过程的编程方法了。游标就是这种编程方式的体现。如果你之前已经有了一些面向过程的编程经验,那么对于游标的理解也会比较容易。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《SQL必知必会》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(26)

  • ahazxc
    想问下老师,在第二个例子中,第一次游标获取数据后,按条件更新数据后,为啥还要再fetch一遍呢?
    2019-07-17
    1
    8
  • 极客不落🐒
    面向集合思维方式的训练,有个在线的游戏,可以帮忙大家:
    www.setgame.com/puzzle/set.htm

    关于面向集合的思考,《Oracle SQL高级编程》一书里有个专门的章节介绍:
    http://m.ituring.com.cn/article/472
    2019-07-17
    1
    7
  • ABC
    老师这些例子是在MySQL的客户端命令行里面运行吗?在navicat里面运行好几个例子都没反应..
    2019-07-18
    5
  • 阿恺
    例子运行会报告:ERROR 1243 (HY000): Unknown prepared statement handler (cur_hero) given to DEALLOCATE PREPARE。 在MYSQL官网上的例子(https://dev.mysql.com/doc/refman/5.7/en/cursors.html)并没有 DEALLOCATE PREPARE 这一步。我理解DECLARE只是做一个变量声明,就如同DECLARE hp INT。过程结束,应该就是生命周期的结束。精简例子,只有声明CURSOR和释放CURSOR,同样报错。
    2019-07-18
    1
    4
  • 大斌
    我理解游标的作用:
    在进行一些复杂计算的时候可以使用游标,因为自带的没有这么复杂的计算,需要自己进行定制,

    我理解的面向过程和面向集合的编程方式的区别:
    面向过程是结构化编程,是对解决问题步骤的分析
    面向集合是属于抽象式的,把解决步骤模块化来复用
    2019-07-22
    1
  • 夜路破晓
    简单理解就是把操作鼠标的动作用存储过程封装起来从而实现面对大批量数据重复操作的自动化。
    这种情况我选择用编程比如python来解决,除非是那种有定期更新要求的定制宽表,可以考虑在定制宽表的基础加个游标以便实现自动化定期更新的要求。
    2019-07-17
    1
  • 我行我素
    不使用游标,使用case when then 也能完成物攻的那个sql吧
    2019-07-17
    1
    1
  • 林彦
    面向集合是通过属性来划分数据获取结果,面向过程是通过对每个/条数据进行处理。
    请问老师文中提到的游标的比较常见的,或能避免其缺点的替代方式有哪些?有哪些场景又必须要用游标?
    谢谢。
    2019-07-17
    1
  • Penn
    面向过程和面向集合,最终的目的都是得到一个计算结果,不同点是,面向过程通过描述how来计算结果,面向集合通过描述what来获得结果;比如需要计算一篮子豆子中红豆的个数,面向过程时,我可以用眼睛筛选红豆子,也可以用仪器筛选,关键是方法需要自己找;而面向集合只需要喊一声:我要红豆子,问题就解决了,只关心最终的结果
    2019-07-17
    1
    1
  • 再次回顾学习一次SQL,游标自我理解就想像鼠标的光标一样可以对每个数据进行扫描,可以到达每个数据的位置。总结游标的使用步骤定义游标,用变量接收游标是否结束,打开游标,游标中取得数据,关闭游标,释放游标。
    2019-11-06
  • Coool
    复制的老师的代码,但是运行出来,结果都是一样的,求解答?
    id attack_growth attack_growth(1)
    10000 12 12
    10001 11 11
    10002 11 11
    10003 8 8
    10004 12 12
    10005 13 13
    10006 10 10
    10007 11 11
    10008 9 9
    10009 9 9
    10010 9 9
    10011 9 9
    10012 9 9
    10013 12 12
    10014 10 10
    10015 8 8
    10016 10 10
    10017 11 11
    10018 12 12
    10019 17 17
    10020 13 13
    10021 16 16
    10022 17 17
    10023 17 17
    10024 16 16
    10025 15 15
    10026 17 17
    10027 15 15
    10028 11 11
    10029 9 9
    10030 12 12
    10031 9 9
    10032 9 9
    10033 9 9
    10034 11 11
    10035 9 9
    10036 9 9
    10037 9 9
    10038 9 9
    10039 11 11
    10040 9 9
    10041 8 8
    10042 10 10
    10043 9 9
    10044 9 9
    10045 10 10
    10046 8 8
    10047 10 10
    10048 10 10
    10049 9 9
    10050 14 14
    10051 15 15
    10052 13 13
    10053 11 11
    10054 15 15
    10055 11 11
    10056 13 13
    10057 13 13
    10058 14 14
    10059 13 13
    10060 13 13
    10061 12 12
    10062 11 11
    10063 11 11
    10064 18 18
    10065 15 15
    10066 15 15
    10067 11 11
    10068 16 16
    2019-10-23
  • 飞翔
    老师 游标是不是有防止内存被撑爆的作用, 比如要获取1百万条数据,假设直接都读取到内存中,内存搁不下,使用游标获取1百万条 貌似就没问题
    2019-09-24
  • GLADIATOR
    英语单词发音可不可以准点,稍微看一下音标
    2019-09-16
  • Danpier

    DEALLOCATE PREPARE 这个查了官方文档5.5和8.0,都说明这个语句是用于释放 PREPARE 语句,而没有提到释放游标,谷歌也没查到相关用法,应该是说错了吧?
    第二个例子 FETCH 放在repeat内部第一行就行,不知为什么要在循环外和循环尾部都加一句?
    2019-07-25
  • Ronnyz
    在Navicat运行例子出现报错ERROR 1243,解决办法就是去掉 DEALLOCATE PREPARE cur_hero
    2019-07-24
  • 自主
    我想问问游标溢出,什么是游标溢出,标准是什么?
    2019-07-22
  • linus
    第一个示例报如下错,麻烦大佬瞅一下,给个回复,谢谢
    [SQL]call calc_hp_max(10)

    [Err] 1318 - Incorrect number of arguments for PROCEDURE help.calc_hp_max; expected 0, got 1
    2019-07-19
    2
  • 华夏
    IF temp_growth < 5 THEN
    IF temp_diff > 200 THEN
    SET temp_growth = temp_growth * 1.1;
    ELSEIF temp_diff >= 150 THEN
    SET temp_growth = temp_growth * 1.08;
    ELSEIF temp_diff < 150 THEN
    SET temp_growth = temp_growth * 1.07;
    END IF;
    ELSEIF temp_growth < 10 THEN
    SET temp_growth = temp_growth * 1.05;
    条件判断也可以写成这样哈。因为上文if>200,elseif就默认<=200。后面同理。
    2019-07-19
  • 算盘Man
    DECLARE cur_hero CURSOR FOR
    SELECT hp_max FROM heros
    > 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DECLARE cur_hero CURSOR FOR
    SELECT hp_max FROM heros' at line 1
    > 时间: 0s
    请教陈老师 为什么复制您的代码会在Navicat里会报错啊 谢谢
    2019-07-19
    2
  • ttttt
    运行最后一个例子alter_attack_growth时,结果运行正确。看着逻辑也对。
    报这个错误。
    1243 - Unknown prepared statement handler (cur_hero) given to DEALLOCATE PREPARE, Time: 0.070000s
    2019-07-18
收起评论
26
返回
顶部