博文一

在使用 mysql_query() 进行一次查询后,一般要用这两个函数之一来把结果存到一个 MYSQL_RES * 变量中。

两者的主要区别是,mysql_use_result() 的结果必须“一次性用完”,也就是说用它得到一个
result 后,必须反复用 mysql_fetch_row() 读取其结果直至该函数返回 null 为止,否则如果你再次进行 mysql
查询,会得到 “Commands out of sync; you can’t run this command now” 的错误。而
mysql_store_result() 得到 result
是存下来的,你无需把全部行结果读完,就可以进行另外的查询。比如你进行一个查询,得到一系列记录,再根据这些结果,用一个循环再进行数据库查询,就只能
用 mysql_store_result() 。

博文二

对于成功检索了数据的每个查询(SELECT、SHOW、DESCRIBE、EXPLAIN、CHECK TABLE 等),必须调用
mysql_store_result() 或 mysql_use_result() 。对于其他查询,不需要调用
mysql_store_result() 或 mysql_use_result() ,但是如果在任何情况下均调用了
mysql_store_result() ,它也不会导致任何伤害或性能降低。通过检查 mysql_store_result() 是否返回
0(NULL) ,可检测查询是否没有结果集(以后会更多)。

如果希望了解查询是否应返回结果集,可使用 mysql_field_count() 进行检查。mysql_store_result() 将查询的全部结果读取到客户端,分配 1 个 MYSQL_RES 结构,并将结果置于该结构中。

如果查询未返回结果集,mysql_store_result() 将返回 NULL 指针(例如,如果查询是 INSERT 语句)。

如果读取结果集失败,mysql_store_result() 也会返回 NULL 指针。通过检查
mysql_error() 是否返回非空字符串,mysql_errno() 是否返回非 0 值,或 mysql_field_count()
是否返回 0 ,可以检查是否出现了错误。如果未返回行,将返回空的结果集。(空结果集设置不同于作为返回值的空指针)。一旦调用了
mysql_store_result() 并获得了不是 NULL 指针的结果,可调用 mysql_num_rows() 来找出结果集中的行数。

可以调用 mysql_fetch_row() 来获取结果集中的行,或调用
mysql_row_seek() 和 mysql_row_tell() 来获取或设置结果集中的当前行位置。一旦完成了对结果集的操作,必须调用
mysql_free_result() 。

返回值

具有多个结果的 MYSQL_RES 结果集合。如果出现错误,返回 NULL 。

错误

如果成功,mysql_store_result() 将复位 mysql_error() 和 mysql_errno() 。

· CR_COMMANDS_OUT_OF_SYNC

以不恰当的顺序执行了命令。

· CR_OUT_OF_MEMORY

内存溢出。

· CR_SERVER_GONE_ERROR

MySQL服务器不可用。

· CR_SERVER_LOST

在查询过程中,与服务器的连接丢失。

· CR_UNKNOWN_ERROR

出现未知错误。

博文三

当调用时,mysql_store_result() 立即检索所有的行,而 mysql_use_result()
启动查询,但实际上并未获取任何行,mysql_store_result() 假设随后会调用 mysql_fetch_row()
检索记录。这些行检索的不同方法引起两者在其他方面的不同。本节加以比较,以便了解如何选择最适合应用程序的方法。

当 mysql_store_result()
从服务器上检索结果集时,就提取了行,并为之分配内存,存储到客户机中,随后调用 mysql_fetch_row()
就再也不会返回错误,因为它仅仅是把行脱离了已经保留结果集的数据结构。mysql_fetch_row() 返回 NULL
始终表示已经到达结果集的末端。相反,mysql_use_result()本身不检索任何行,而只是启动一个逐行的检索,就是说必须对每行调用
mysql_fetch_row() 来自己完成。既然如此,虽然正常情况下,mysql_fetch_row() 返回 NULL
仍然表示此时已到达结果集的末端,但也可能表示在与服务器通信时发生错误。可通过调用 mysql_errno() 和mysql_error()
将两者区分开来。

与 mysql_use_result() 相比,mysql_store_result()
有着较高的内存和处理需求,因为是在客户机上维护整个结果集,所以内存分配和创建数据结构的耗费是非常巨大的,要冒着溢出内存的危险来检索大型结果集,如
果想一次检索多个行,可用 mysql_use_result()。mysql_use_result()
有着较低的内存需求,因为只需给每次处理的单行分配足够的空间。这样速度就较快,因为不必为结果集建立复杂的数据结构。另一方
面,mysql_use_result() 把较大的负载加到了服务器上,它必须保留结果集中的行,直到客户机看起来适合检索所有的行。

博文四

客户端处理结果集的方式有两种。一种方式是,通过调用
mysql_store_result(),一次性地检索整个结果集。该函数能从服务器获得查询返回的所有行,并将它们保存在客户端。第二种方式是针对客
户端的,通过调用
mysql_use_result(),对“按行”结果集检索进行初始化处理。该函数能初始化检索结果,但不能从服务器获得任何实际行。

在这两种情况下,均能通过调用 mysql_fetch_row() 访问行。通过
mysql_store_result(),mysql_fetch_row()
能够访问以前从服务器获得的行。通过mysql_use_result(),mysql_fetch_row()
能够实际地检索来自服务器的行。通过调用 mysql_fetch_lengths(),能获得关于各行中数据大小的信息。

完成结果集操作后,请调用 mysql_free_result() 释放结果集使用的内存。

这两种检索机制是互补的。客户端程序应选择最能满足其要求的方法。实际上,客户端最常使用的是 mysql_store_result() 。

mysql_store_result() 的 1 个优点在于,由于将行全部提取到了客户端上,你不仅能连续访问行,还能使用
mysql_data_seek() 或 mysql_row_seek()在结果集中向前或向后移动,以更改结果集内当前行的位置。通过调用
mysql_num_rows(),还能发现有多少行。另一方面,对于大的结果集,mysql_store_result()
所需的内存可能会很大,你很可能遇到内存溢出状况。

mysql_use_result() 的 1
个优点在于,客户端所需的用于结果集的内存较少,原因在于,一次它仅维护一行(由于分配开销较低,mysql_use_result()能更快)。它的缺
点在于,你必须快速处理每一行以避免妨碍服务器,你不能随机访问结果集中的行(只能连续访问行),你不知道结果集中有多少行,直至全部检索了它们为止。不
仅如此,即使在检索过程中你判定已找到所寻找的信息,也必须检索所有的行。

下面是官网说法:

===============

【22.8.15. Common Questions and Problems When Using the C API

【22.8.15.1. Why mysql_store_result() Sometimes Returns NULL After mysql_query() Returns Success】

成功调用 mysql_query() 后,调用 mysql_store_result() 却返回 NULL 是可能的。当发生该情况时,有可能是因为下面情况的出现:

  • 出现 malloc() 失败的情况(例如,获得的结果集太大)。
  • 调用 mysql_store_result() 时,当前使用的 TCP 连接已意外断开,导致无法读取数据。
  • 调用 mysql_store_result() 后确实应该无数据返回(例如调用的是 INSERT、UPDATE 或 DELETE)。

无论何时,你都可以通过调用 mysql_field_count() 来确定前一条执行的语句是否产生了非空结果集。如果
mysql_field_count() 返回的是 0 ,那么结果集必然是空的(返回 NULL ),最后调用的查询必定为不会返回结果集的语句(例如
INSERT 或 DELETE )。如果 mysql_field_count() 返回非 0 值,那么最后一条查询语句应该返回非空结果集。
(如果此时你获得了空结果集)你可以通过调用 mysql_error() 或者 mysql_errno() 来查看错误信息。

【22.8.15.2. What Results You Can Get from a Query】

在调用查询命令后除了可以获得结果集外,还可以通过如下命令获得更多信息:

  • 调用 mysql_affected_rows() 会返回执行最后一条查询语句(如 INSERT、UPDATE 或 DELETE )后所影响的 row 的数量。
  • 快速重建表,可以使用 TRUNCATE TABLE 。
  • 调用 mysql_num_rows() 会返回结果集中的 row 的数量。如果是使用
    mysql_store_result() 来获取结果集,那么只要在 mysql_store_result() 返回后,立刻就可以调用
    mysql_num_rows() 来获取 row 的数量。如果是使用 mysql_use_result() 来获取结果集,那么必须在使用
    mysql_fetch_row() 获取到结果集的全部 row 后,才能调用 mysql_num_rows() 来后去 row 的数量。
  • 调用 mysql_insert_id() 会返回向具有 AUTO_INCREMENT 索引的表插入 row 时所产生的最后一个 ID 。
  • 有一些查询(如 LOAD DATA INFILE …, INSERT INTO … SELECT …, UPDATE)会返回额外的信息。其结果可以通过 mysql_info() 来获取。

【Appendix C. Errors, Error Codes, and Common Problems】

【C.5.2. Common Errors When Using MySQL Programs】

【C.5.2.14. Commands out of sync】

如果你遇到了 “Commands out of sync” 错误,你的客户端程序将不能够在当下成功执行(有结果集返回的)新的查询命令,因为你以错误的执行序列进行了调用。

例如,当你在调用 mysql_use_result() 后,在未调用 mysql_free_result()
之前,又执行了一个新的查询操作就会出现上述问题。还有一种情况是,当你连续调用能够获得结果集的查询命令,却在其连续调用中间未调用
mysql_use_result() 或 mysql_store_result() 来获取结果集的情况。

=============

有了上面的研究,已经很清楚两者之前的差别了:

  • 分别会消耗客户端或服务器的内存;
  • 执行后续操作的约束不同。

决定选择的关键还是要看,客户端程序是否关心结果集的内容。就 modb 而言,不太关心具体内容,只要知道成功还是失败就可以了。所以我只需要确定调用 mysql_query() 是否返回成功就可以了。

参考:

http://bbs.csdn.net/topics/210011435

mysql_use_result & mysql_store_result & MYSQLI_ASYNC的更多相关文章

  1. 使用 mysql_use_result 还是使用 mysql_store_result?

    From: http://my.oschina.net/moooofly/blog/186456 本文整理了关于“使用 mysql_use_result 还是 mysql_store_result”的 ...

  2. mysql_use_result的使用

    对于每个可以产生一个结果集的命令(比如select.show.describe, explain, check_table等等),发起mysql_query或者mysql_real_query之后,你 ...

  3. 有关Mysql的mysql_store_result函数返回NULL的情况以及其他注意事项

    成功调用mysql_query()后,mysql_store_result()能够返回NULL.出现该情况时,表明出现了下述条件之一: ·         出现了malloc()故障(例如,如果结果集 ...

  4. MySQL数据库在linux的安装,编程与操作

    一.安装 ubuntu上安装MySQL非常简单只需要几条命令就可以完成. 1. sudo apt-get install mysql-server   2. apt-get isntall mysql ...

  5. mysql C API的使用

    <MySQL++简介>介绍了如何使用C++来访问mysql,本文记录下使用C API访问mysql,mysql++就是对本文介绍的C-API的封装. 常用函数(名字就能告诉我们用法): M ...

  6. 转 用C API 操作MySQL数据库

    用C API 操作MySQL数据库 参考MYSQL的帮助文档整理 这里归纳了C API可使用的函数,并在下一节详细介绍了它们.请参见25.2.3节,“C API函数描述”. 函数 描述 mysql_a ...

  7. mysql5.5手册读书日记(4)

    <?php /* InnoDB事务模型和锁定 15.2.10.1. InnoDB锁定模式 15.2.10.2. InnoDB和AUTOCOMMIT 15.2.10.3. InnoDB和TRANS ...

  8. C语言操作mysql

    php中 mysqli, pdo 可以用 mysqlnd 或 libmysqlclient 实现 前者 从 php 5.3.0起已内置到php中, 并且支持更多的特性,推荐用 mysqlnd mysq ...

  9. C++连接mysql的两种方式(ADO连接和mysql api连接)

    一.ADO连接mysql 1.安装mysql-5.5.20-win32.msi和mysql-connector-odbc-5.3.4-win32.msi(一般两个安装程序要匹配,否则可能连接不上)  ...

随机推荐

  1. 为什么Scrum不行?

    这篇文章的原文在这里(原文链接)(下文不是全译,也不是部分译,我只是把其总结,有我自己的发挥,但是原意大致不变),这篇文章完全是在调侃Scrum的,作者第一段就是一个免费声明,其说他是Scrum和其它 ...

  2. Arcgis license 服务无法启动的解决问题

    来自:http://blog.csdn.net/u013719339/article/details/51240312 1.检查服务开没开.打开资源管理器然后按照下面就出现了.也可以打开运行——ser ...

  3. 每天进步一点点——关于SSD写入放大问题

    转载请说明出处:http://blog.csdn.net/cywosp/article/details/29812433 1. 关于SSD的写入放大     之前在SSD(Solid State Dr ...

  4. JACOB的语法

    转自:http://www.bitscn.com/pdb/java/200904/161117.html 如果你想写一个JAVA代码,其中需要调用JACOB提供的功能,而你还是新手,也许篇文章会大大降 ...

  5. 第一章 Actionscript学习基本知识笔记及flashdevelop软件的安装问题

    OOP:封装.继承.多态. Pubilc :完全公开. Internal:包内类成员可以互相访问. Private:仅当前类可以访问. Protected:当前类和当前类的子类可以访问. 被关键词fi ...

  6. [Linux] ubuntu下查看CHM的软件

    本文旨在介绍linux下的常见chm阅读软件及其安装,并针对一些问题给出解决方法. 一.CHMSEE 这个比较常见了,呵呵. 安装: sudo apt-get install chmsee 之后在应用 ...

  7. java 五子棋之人机对战思路详解

    最近做了五子棋,记录下自己完成五子棋的人机对战的思路. 首先,思路是这样的:每当人手动下一颗棋子(黑子)的时候,应当遍历它周围棋子的情况,并赋予周围棋子一定的权值,当在机器要下棋子(白子)守护之前,会 ...

  8. Linux下Anaconda的安装使用与卸载及问题解决

    1. 安装 到官网下载对应的版本文件:Download Anaconda Now! 下载完之后,在终端输入: bash 下载好的文件 整个过程点几下回车就好了.但是到最后一步,会提示是否把anacon ...

  9. js执行eval()抛出异常SyntaxError

    try{ eval("("+data+")"); }catch(err) { location.href = window.location.href; }

  10. Windows Xp不用安装软件管理多个远程桌面连接

    一直使用系统默认的Mstsc来进行远程连接,但如果要连接N个远程的话就比较麻烦 之前也找过第三方的管理软件如:mRemoteNG 此软件有优点就不说了,但我在使用此软件时有一个很大的问题,就是如果一个 ...