Mysql入门系列:MYSQL客户机程序2—增加错误检查

2016-02-19 15:24 1 1 收藏

下面是个Mysql入门系列:MYSQL客户机程序2—增加错误检查教程,撑握了其技术要点,学起来就简单多了。赶紧跟着图老师小编一起来看看吧!

【 tulaoshi.com - 编程语言 】

  6.3 客户机程序2增加错误检查

  我们的第二个客户机程序将像第一个客户机程序一样,但是将修改它们,考虑错误出现的可能性。将错误检查作为读者的练习这样的项目在编程文献中相当常见,这或许是因为检查错误相当令人讨厌。但是,我赞同这种观点,即MySQL客户机程序应该测试错误条件

  并适当地进行回应。由于某种原因,返回状态值的客户机库的调用做这些事情,而且您要承担忽略它们的后果。您最终还是要试图捕获由于没有错误检查而出现在程序中的错误,这些程序的用户会对程序运行如此不规律感到奇怪。考虑我们的程序,客户机程序1。如何知道它是否真正连接到服务器上?可以通过查看服务器的日志,找出与运行程序时间相应的Connect和Quit事件:

  

  这条消息表示根本没有创建连接。不幸的是,客户机程序1没有告诉我们出现的这些结果。实际上它不能。它不能实现任何错误检查,所以它甚至不知道自己发生了什么事。无论如何,当然不一定必须查看日志来寻找是否能连接到服务器!让我们立刻改正它。在MySQL客户机库中返回值的例程基本上以下列两种方式之一表示成功或失败:

  ■ 成功时,值的指针函数返回一个非NULL 指针,失败时返回NULL(在这里NULL 的意思是C NULL 指针,而不是MySQLNULL 列值)。迄今为止,我们使用的客户机库的例程mysql_init() 和mysql_real_connect() 都用返回连接处理程序的指针来表示成功, NULL 表示失败。

  ■ 整型数值的函数一般成功返回0,失败返回非0。不要测试特定的非0值,如- 1。因为当失败时,并不保证客户机库函数返回任何特定的值。有时,您可能会看到像如下的较旧的错误地测试返回值的代码:

  

  这个测试可能工作,也可能不工作。MySQLAPI 不将任何非0错误的返回指定为特定的值,而只判断它(显然地)是否为0。这个测试应该写成下面两段之一:

  

  或如下所示:

  

  这两个测试是等价的。如果审核MySQL的源代码,则可以发现,它基本上用第一种形式测试,因为这编写起来更简短。

  不是每个API 调用都返回值。我们使用的另一个客户机例程mysql_close() 就不返回值(它如何失败?失败了又如何?无论如何,都要进行连接)。

  当客户机库调用失败,并且需要有关失败的详细信息时, API 中的两个调用都是有用的。mysql_error() 返回包括错误信息的字符串,而mysql_errno() 返回数值代码。应该在错误出现以后立刻调用它们,因为如果发布另一个返回状态的API 调用,则从mysql_error() 或mysql_errno() 获取的任何错误信息都将来自于后面的调用。

  一般来说,程序的用户查看错误字符串比查看错误代码更有启发。如果只报告两者中的一个,则建议报告字符串。出于全面考虑,本章的这个样例报告两个值。考虑前述的讨论,我们将编写第二个客户机程序,即客户机程序2。它类似于客户机程序

  1,但是适当地增加了错误检查代码。源文件client2.c 如下所示:

  

  

  这个错误检查的逻辑是,如果失败,则mysql_init() 和mysql_real_connect() 都返回NULL。请注意,尽管这个程序检查mysql_init() 返回的值,但是,如果它失败,却不调用错误报告函数。这是因为当mysql_init() 失败时,不能假设连接处理程序包括任何有意义的信息。

  相反,如果mysql_real_connect() 失败了,则连接处理程序并不反映有效的连接,但是的确包括传送给错误报告函数的错误信息(不要将该处理程序传送给任何其他的客户机例程!因为它们一般假设是一个有效连接,所以您的程序可能崩溃)。编译和连接客户机程序2,然后试着运行它:

  % client2

  如果客户机程序2没有别输出,则连接成功。另一方面,可能会如下所示:

  

  这个输出表示没有创建连接,并说明为什么。或者,它还表示我们的第一个程序,即客户机程序1,没有成功地连接到服务器(毕竟客户机程序1使用同样的连接参数)!而在那时我们不知道,因为客户机程序1没有错误检查。而客户机程序2做检查,所以当出问题时,它可以告知我们。这就是应该始终测试API 函数返回值的原因。

  MySQL邮件清单问题经常是与错误检查有关的。典型的问题是当发送这个查询时,为什么我的程序崩溃了?或我的程序怎么没有返回任何东西?在许多情况下,在查询发布以前,有疑问的程序不检查在发布该查询前是否成功地建立了连接,或者不检查在试着检

  索结果前确保服务器成功执行该查询。不要假定每个客户机库都调用成功。

  本章下面的例子完成错误检查,而且也应该这样。看起来它好像有更多的工作,但是从长远地运行来看,它的工作实际上是少的,因为您化费了更少的时间来捕获错综复杂的问题。在第7章Perl DBI API和第8章PHP API中,也使用这种检查错误的方法。

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  现在,当运行客户机2的程序时,假设看到拒绝访问( Access denied)的消息。如何改正这个问题呢?一种可能是将主机名称、用户名称和口令的#define 行更改为允许访问服务器的值。这是有好处的,在这个意义上,至少应该能做一个连接。但是,这些值是程序中的固定编码。所以笔者建议不要用这种方法,特别是对口令值。当将自己的程序编译为二进制格式时,您可能认为口令隐藏起来了,但是,如果有人在程序上运行strings,则它根本隐藏不住(更不用说明读取访问源文件的人根本不用做一点工作,就可以获取口令)。

  在客户机程序4运行时获取连接参数一节中我们将处理访问的问题。首先,笔者

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  想说明编写连接代码的一些其他方法。

  查看全套"Mysql入门系列教程"

来源:https://www.tulaoshi.com/n/20160219/1609562.html

延伸阅读
在本书的这部分中,我们将讨论编写自己的访问MySQL数据库的程序所需要知道的内容。MySQL有一组实用程序。例如, mysqldump 导出表的上下文和结构定义, mysqlimport将数据文件加载到表中, mysqladmin 实现管理w操作, mysql可以使用户与服务器交互来执行任意的查询。每个标准的MySQL实用程序都倾向于小巧,重点放在程序可完成特定的、有...
序列不从1开始的另一个原因从技术的角度来说可能不值一提。例如,在分配会员号时,序列号不要从1开始,以免出现关于谁是第一号的政治争论。 (4) 不用AUTO_INCREMENT 生成序列生成序列号的另一个方法根本就不需要使用AUTO_INCREMENT 列。它利用取一个参数的L A S T _ INSERT_ID( ) 函数的变量来生成序列号。(这种形式在MySQL3.22.9. ...
4.6 管理员的优化 前面各段介绍了普通的MySQL用户利用表创建和索引操作,以及利用查询的编写能够进行的优化。不过,还有一些只能由MySQL管理员和系统管理员来完成的优化,这些管理员在MySQL服务器或运行MySQL的机器上具有控制权。有的服务器参数直接适用于查询处理,可将它们打开。而有的硬件配置问题直接影响查询处理速度,应该对它...
3.6 检索记录 除非最终检索它们并利用它们来做点事情,否则将记录放入数据库没什么好处。这就是SELECT 语句的用途,即帮助取出数据。SELECT 大概是SQL 语言中最常用的语句,而且怎样使用它也最为讲究;用它来选择记录可能相当复杂,可能会涉及许多表中列之间的比较。SELECT 语句的语法如下: 除了词 S E L E C T和说明希...
关系数据库的世界是一个表与集合、表与集合上的运算占统治地位的世界。数据库是一个表的集合,而表又是行和列的集合。在发布一条SELECT 查询从表中进行检索行时,得到另一个行和列的集合。这些都是一些抽象的概念,对于数据库系统用来操纵表中数据的基本 表示没有多少参考价值。另一个抽象概念是,表上的运算都同时进行;查询是一种概...

经验教程

404

收藏

56
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部