第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定

解析MySQL存儲過程的游標執(zhí)行過程

標簽:
MySQL
  • GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。

内容提纲

一、测试环境搭建

二、执行过程解析

三、注意事项

一、测试环境搭建

首先创建一张表,并插入几行数据字段:

CREATE TABLE t (s1 INT, s2 char(100),PRIMARY KEY (s1));
INSERT INTO t values(1,'aaa');
INSERT INTO t values(2,'bbb');
INSERT INTO t values(3,'ccc');

接着创建存储过程,这里的v_total用于判断数据行数。

因为MySQL游标获取完后,最后一行没有退出机制。所以不进行判断是否取完最后一行,就继续取数会发生报错。

DELIMITER ;;
  CREATE PROCEDURE test_mysql_cursor_loop()
    BEGIN
      declare v_total int default 0; 
      declare i int default 0; 
      declare str1 int;
      declare str2 varchar(255);
      DECLARE stuCursor CURSOR FOR SELECT s1,s2 FROM t;
      select count(s2) into v_total from t;
      OPEN stuCursor;
      stuLoop:LOOP
        IF i = v_total THEN LEAVE stuLoop; end if;
        FETCH stuCursor INTO str1,str2;
          SELECT str1,str2;
          set i = i+1;
      end loop stuLoop;
    END;;
DELIMITER ;

二、执行过程解析

这个存储过程在MySQL内部转化为存储过程指令如下:

mysql> show PROCEDURE code test_mysql_cursor_loop;
+-----+---------------------------------------------+
| Pos | Instruction                                 |
+-----+---------------------------------------------+
|   0 | set v_total@0 0                             |
|   1 | set i@1 0                                   |
|   2 | set str1@2 NULL                             |
|   3 | set str2@3 NULL                             |
|   4 | cpush stuCursor@0: SELECT s1,s2 FROM t      |
|   5 | stmt "select count(s2) into v_total from t" |
|   6 | copen stuCursor@0                           |
|   7 | jump_if_not 9(9) (i@1 = v_total@0)          |
|   8 | jump 13                                     |
|   9 | cfetch stuCursor@0 str1@2 str2@3            |
|  10 | stmt "SELECT str1,str2"                     |
|  11 | set i@1 (i@1 + 1)                           |
|  12 | jump 7                                      |
|  13 | cclose stuCursor@0                          |
|  14 | cpop 1                                      |
+-----+---------------------------------------------+
15 rows in set (0.00 sec)

其中:

  • v_total@0的 @0 代表这是第一个自定义变量。

  • stuCursor@0的 @0 代表这是第一个cursor变量。

从指令可以看出cursor的运行需要经过几个过程:

1、cpush

这个用于注册一个cursor,初始化堆栈。

2、copen

这里会先运行SELECT s1,s2 FROM t指令,让cursor获得表的列信息,然后调用cpush,经过cpush->open来打开一个cursor,用于后续获取表数据。

3、cfetch

这个用于从cursor获取的数据赋值给自定义变量str1,str2,然后传递给client端显示。注意到这里用了jump 7来循环取数据。

4、cclose

关闭cursor。

5、cpop

把当前cursor从堆栈释放掉。

上面循环取数和退出机制如下:

jump_if_not 9(9) (i@1 = v_total@0)用于判断i@1是否等于v_total@0,如果不等于的话当前指令就跳转到第9个指令,继续执行cfetch。

如果i@1等于v_total@0的话就继续执行下一条jump 13关闭cursor退出当前循环。set i@1 (i@1 + 1)用于计数,jump 7用于继续循环取数。

三、注意事项

str1和str2的类型和数量必须与declare cursor的一致,如果声明不正确就会导致cfetch出错。

因为declare str1和str2之后,mysql就会对这两个列建立一张临时表,当cfetch数据之后就会把数据存入这张表,后续用户select的时候就从这张临时表取数据来显示,所以就必须进行正确的变量声明。

Enjoy MySQL :)

點擊查看更多內(nèi)容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優(yōu)質(zhì)文章

正在加載中
數(shù)據(jù)庫工程師
手記
粉絲
6
獲贊與收藏
66

關(guān)注作者,訂閱最新文章

閱讀免費教程

  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優(yōu)惠券免費領(lǐng)

立即參與 放棄機會
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號

舉報

0/150
提交
取消