来源:
https://dev.mysql.com/doc/internals/en/multi-resultset.html
服务器向客户端发送结果集
官方用了存储过程来做解释(insert)
CREATE TEMPORARY TABLE ins ( id INT );
DROP PROCEDURE IF EXISTS multi;
DELIMITER $$
CREATE PROCEDURE multi() BEGIN
SELECT 1;
SELECT 1;
INSERT INTO ins VALUES (1);
INSERT INTO ins VALUES (2);
END$$
DELIMITER ;
CALL multi();
DROP TABLE ins;
服务器返回:
第一轮发送结果:
01 00 00 01 01 17 00 00 02 03 64 65 66 00 00 00 ..........def...
01 31 00 0c 3f 00 01 00 00 00 08 81 00 00 00 00 .1..?...........
05 00 00 03 fe 00 00 0a 00 02 00 00 04 01 31 05 ..............1.
00 00 05 fe 00 00 0a 00 ........
拆分:
(1)01 00 00 01 01 列数
(2)17 00 00 02 03 64 65 66 00 00 00 01 31 00 0c 3f 00 01 00 00 00 08 81 00 00 00 00 定义包
(3)05 00 00 03 fe 00 00 0a 00 EOF_packet
(4)02 00 00 04 01 31 数据包,31的值为1
(5)05 00 00 05 fe 00 00 0a 00 EOF_packet
设置标志位 0x000a ,即 SERVER_MORE_RESULTS_EXISTS 表明还有第二轮数据发送。
第二轮发送结果
01 00 00 06 01 17 00 00 07 03 64 65 66 00 00 00 ..........def...
01 31 00 0c 3f 00 01 00 00 00 08 81 00 00 00 00 .1..?...........
05 00 00 08 fe 00 00 0a 00 02 00 00 09 01 31 05 ..............1.
00 00 0a fe 00 00 0a 00 ........
拆分:
(6)01 00 00 06 01 列数01 = 1
(7)17 00 00 07 03 64 65 66 00 00 00 01 31 00 0c 3f 00 01 00 00 00 08 81 00 00 00 00 定义包
(8)05 00 00 08 fe 00 00 0a 00 EOF_packet,标记为status = 0a 00 = 0x000a = 0000 0000 0000 1010 = 8+2
(9)02 00 00 09 01 31 数据包,31的值= 1
(10)05 00 00 0a fe 00 00 0a 00 EOF_packet
最后一轮(第三轮)发送(空)结果集
07 00 00 0b 00 01 00 02 00 00 00 ...........
拆分:
(11)07 00 00 0b 00 01 00 02 00 00 00
affected rows = 01
(最后一条语句的影响数目,即第二轮返回了1条数据;
虽然样例中有两轮发送,有2条,但是最后一轮的OK_packet只返回1条;
如果最后一条语句是select,那么返回的结果印象行数为0,应该为
07 00 00 0b 00 00 00 02 00 00 00
);
last insert-id = 00;
status flag 02 00 = 0x0002
特别批注
- 如果客户端支持CLIENT_DEPRECATE_EOF,则每个批次都要发送OK包。这里第一轮和第二轮用的是EOF包;
- 如果是一个空的结果集,那么就发送一个OK包;
- 其他情况,都需要发送EOF包;