第25章:API和库 / 25.2. MySQL C API / 25.2.13. 使用C API时的常见问题
'
25.2.13.1. 为什么在mysql_query()返回成功后,mysql_store_result()有时会返回NULL
25.2.13.2. What Results You Can Get from a Query
25.2.13.3. 如何获得上次插入行的唯一ID
25.2.13.4. 与C API有关的问题

25.2.13.1. 为什么在mysql_query()返回成功后,mysql_store_result()有时会返回NULL

成功调用mysql_query()后,mysql_store_result()能够返回NULL。出现该情况时,表明出现了下述条件之一:

·         出现了malloc()故障(例如,如果结果集过大)。

·         无法读取数据(在连接上出现了错误)。

·         查询未返回数据(例如,它是INSERTUPDATEDELETE)。

通过调用mysql_field_count()始终能检查语句是否应生成非空结果。如果mysql_field_count()返回0,结果为空,而且上一个查询是未返回值的语句(例如INSERTDELETE)。如果mysql_field_count()返回非0值,语句应生成非空结果。关于这方面的示例,请参见mysql_field_count()函数介绍。

通过调用mysql_error()mysql_errno()可测试是否出现了错误。

25.2.13.2. What Results You Can Get from a Query

除了查询返回的结果集外,还能获取下述信息:

·         执行INSERTUPDATEDELETE时,mysql_affected_rows()返回上次查询影响的行数。

对于快速在创建,请使用TRUNCATE TABLE

·         mysql_num_rows()返回结果集中的行数。使用mysql_store_result(),一旦mysql_store_result()返回,就能调用mysql_num_rows()。使用mysql_use_result(),仅当用mysql_fetch_row()获取了所有行后,才能调用mysql_num_rows()

·         mysql_insert_id()返回上次查询生成的ID,该查询使用AUTO_INCREMENT索引将行插入到表内。请参见25.2.3.36节,“mysql_insert_id()”

·         某些查询(LOAD DATA INFILE ...INSERT INTO ... SELECT ...UPDATE)将返回额外信息。结果由mysql_info()返回。关于它返回的字符串格式,请参见关于mysql_info()的介绍。如果没有额外信息,mysql_info()将返回NULL指针。

25.2.13.3. 如何获得上次插入行的唯一ID

如果将记录插入包含AUTO_INCREMENT列的表中,通过调用mysql_insert_id()函数,可获取保存在该列中的值。

通过执行下述代码,可从C应用程序检查某一值是否保存在AUTO_INCREMENT列中(假定该语句已成功执行)。它能确定查询是否是具有AUTO_INCREMENT索引的INSERT

if ((result = mysql_store_result(&mysql)) == 0 &&
    mysql_field_count(&mysql) == 0 &&
    mysql_insert_id(&mysql) != 0)
{
    used_id = mysql_insert_id(&mysql);
}

关于更多信息,请参见25.2.3.36节,“mysql_insert_id()”

生成新的AUTO_INCREMENT值时,也能与mysql_query()一起通过执行SELECT LAST_INSERT_ID()语句获得它,并从该语句返回的结果集检索该值。

对于LAST_INSERT_ID(),最近生成的ID是在服务器上按连接维护的。它不会被另一个客户端改变。即使用non-magic值(即非Null0值)更新了另一个AUTO_INCREMENT列,也不会更改它。

如果打算使用从某一表生成的ID,并将其插入到第2个表中,可使用如下所示的SQL语句:

INSERT INTO foo (auto,text)
    VALUES(NULL,'text');              # generate ID by inserting NULL
INSERT INTO foo2 (id,text)
    VALUES(LAST_INSERT_ID(),'text');  # use ID in second table

注意,mysql_insert_id()返回保存在AUTO_INCREMENT列中的值,无论该值是因存储NULL0而自动生成的,或是明确指定的,均如此。LAST_INSERT_ID()仅返回自动生成的AUTO_INCREMENT值。如果你保存了除NULL0之外的确切值,不会影响LAST_INSERT_ID()返回的值。

25.2.13.4. 与C API有关的问题

C API链接时,在某些系统上可能出现下述错误:
gcc -g -o client test.o -L/usr/local/lib/mysql -lmysqlclient -lsocket -lnsl
 
Undefined        first referenced
 symbol          in file
floor            /usr/local/lib/mysql/libmysqlclient.a(password.o)
ld: fatal: Symbol referencing errors. No output written to client

如果在你的系统上出现了该情况,必须在编译/链接行的末尾增加“-lm”,通过该方式包含数学库。