mysql c api详解(四)...
时间:2010-08-18 来源:jsufcz
来自:http://hi.baidu.com/lovevc2008/blog/item/4aa3a6231f7cc8f9d6cae214.html
20.4.42 mysql_reload()
int mysql_reload(MYSQL *mysql)
20.4.42.1 说明
要求MySQL服务器再次装载授权表。连接的用户必须拥有reload权限。
不推荐这个函数。最好使用mysql_query()发出一条SQL FLUSH PRIVILEGES语句。
20.4.42.2 返回值
成功,零。如果发生一个错误,非零。
20.4.42.3 错误
CR_COMMANDS_OUT_OF_SYNC 命令以一个不适当的次序被执行。 CR_SERVER_GONE_ERROR MySQL服务器关闭了。 CR_SERVER_LOST 对服务器的连接在查询期间失去。 CR_UNKNOWN_ERROR 发生一个未知的错误。20.4.43 mysql_row_seek()
MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset)
20.4.43.1 说明
设置行光标为在结果集合中的任意行。这要求结果集合结构包含查询的全部结果,这样mysql_row_seek()只能与mysql_store_result()一起使用,而不与mysql_use_result()。
偏移量应该是调用mysql_row_tell()或mysql_row_seek()返回的值。这个值不是简单地一个行号;如果你想要在结果集合内用行号来寻找行,使用mysql_data_seek()。
20.4.43.2 返回值
行光标先前的值。该值可以被传递给随后的mysql_row_seek()调用。
20.4.44 mysql_row_tell()
MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)
20.4.44.1 说明
返回为了mysql_fetch_row()的行光标的当前位置。这个值可以作为一个参数用于mysql_row_seek()。
你应该仅在mysql_store_result()后使用mysql_row_tell(),而不是在mysql_use_result()后。
20.4.44.2 返回值
行光标当前的偏移量。
20.4.45 mysql_select_db()
int mysql_select_db(MYSQL *mysql, const char *db)
20.4.45.1 说明
使得由db指定的数据库成为 在由mysql指定的连接上的缺省(当前)数据库。在随后的查询中,这个数据库对于不包括一个显式的数据库指定符的表的引用是缺省数据库。
除非连接的用户能被认证允许使用数据库,否则mysql_select_db()失败。
20.4.45.2 返回值
成功,零。如果发生一个错误,非零。
20.4.45.3 错误
CR_COMMANDS_OUT_OF_SYNC 命令以一个不适当的次序被执行。 CR_SERVER_GONE_ERROR MySQL服务器关闭了。 CR_SERVER_LOST 对服务器的连接在查询期间失去。 CR_UNKNOWN_ERROR 发生一个未知的错误。20.4.46 mysql_shutdown()
int mysql_shutdown(MYSQL *mysql)
20.4.46.1 说明
让数据库服务器关闭。连接的用户必须有shutdown权限。
20.4.46.2 返回值
成功,零。如果出现一个错误,非零
20.4.46.3 错误
CR_COMMANDS_OUT_OF_SYNC 命令以一个不适当的次序被执行。 CR_SERVER_GONE_ERROR MySQL服务器关闭了。 CR_SERVER_LOST 对服务器的连接在查询期间失去。 CR_UNKNOWN_ERROR 发生一个未知的错误。 20.4.47 mysql_stat()char *mysql_stat(MYSQL *mysql)
20.4.47.1 说明
返回包含类似于由mysqladmin status命令提供的信息的一个字符串。它包括正常运行的秒数和正在运行线程、问题、再次装载和打开的表的数目。
20.4.47.2 返回值
描述服务器状态的一个字符串。如果出现一个错误,NULL。
20.4.47.3 错误
CR_COMMANDS_OUT_OF_SYNC 命令以一个不适当的次序被执行。 CR_SERVER_GONE_ERROR MySQL服务器关闭了。 CR_SERVER_LOST 对服务器的连接在查询期间失去。 CR_UNKNOWN_ERROR 发生一个未知的错误。20.4.48 mysql_store_result()
MYSQL_RES *mysql_store_result(MYSQL *mysql)
20.4.48.1 说明
对于成功地检索数据的每个询问(SELECT、SHOW、DESCRIBE、EXPLAIN),你必须调用mysql_store_result()或mysql_use_result()。
mysql_store_result()读取一个到客户的查询的全部结果,分配一个MYSQL_RES结构,并且把结果放进这个结构中。
如果没有行返回,返回一个空集合集合。(空结果集合不同于一个NULL返回值。)
一旦你调用了mysql_store_result(),你可以调用mysql_num_rows()找出结果集合中有多少行。
你能调用mysql_fetch_row()从结果集合中取出行,或mysql_row_seek()和mysql_row_tell()结果集合中获得或设置当前的行位置。
一旦你用完结果集合,你必须调用mysql_free_result()。
见20.4.51 为什么mysql_query()返回成功后,mysql_store_result()有时返回NULL?。
20.4.48.2 返回值
一个保存结果的MYSQL_RES结构。如果出现一个错误,NULL。
20.4.48.3 错误
CR_COMMANDS_OUT_OF_SYNC 命令以一个不适当的次序被执行。 CR_OUT_OF_MEMORY 内存溢出。 CR_SERVER_GONE_ERROR MySQL服务器关闭了。 CR_SERVER_LOST 对服务器的连接在查询期间失去。 CR_UNKNOWN_ERROR 发生一个未知的错误。20.4.49 mysql_thread_id()
unsigned long mysql_thread_id(MYSQL *mysql)
20.4.49.1 说明
返回当前连接的线程ID。这个值可用作mysql_kill()的一个参数以杀死线程。
如果失去连接并且你用mysql_ping()重新连接,线程ID将改变。这意味着你不应该为以后使用获得线程ID并且存储它,当你需要它时,你应该获得它。
20.4.49.2 返回值
当前连接的线程 ID 。
20.4.50 mysql_use_result()MYSQL_RES *mysql_use_result(MYSQL *mysql)
20.4.50.1 说明
对于成功地检索数据的每个查询(SELECT、SHOW、DESCRIBE、EXPLAIN),你必须调用mysql_store_result()或mysql_use_result()。
mysql_use_result()初始化一个结果集合的检索,但不真正将结果集合读入客户,就象mysql_store_result()那样。相反,必须通过调用mysql_fetch_row()单独检索出每一行,这直接从服务器读出结果而不在一个临时表或本地缓冲区中存储它,它比mysql_store_result()更快一点并且使用较少的内存。客户将只为当前行和一个可能最大max_allowed_packet字节的通信缓冲区分配内存。
在另一方面,如果你在客户端对每一行正在做很多的处理,或如果输出被送到屏幕,用户可以打一个^S(停止滚动),你不应该使用mysql_use_result()。这将阻塞服务器并且阻止另外的线程从数据被取出的任何表中更新数据。
当使用mysql_use_result()时,你必须执行mysql_fetch_row()直到返回一个NULL值,否则未取出的行将作为下一个查询的结果集合一部分被返回。如果你忘记做这个,C API将给出错误Commands out of sync; You can't run this command now!
你不能在一个从mysql_use_result()返回的结果集合上使用mysql_data_seek()、mysql_row_seek()、mysql_row_tell()、mysql_num_rows()或mysql_affected_rows(),你也不能发出另外的查询直到mysql_use_result()完成。(然而,在你取出所有的行以后,mysql_num_rows()将精确地返回取出的行数。)
一旦你用完结果集合,你必须调用mysql_free_result()。
20.4.50.2 返回值
一个MYSQL_RES结果结构。 如果发生一个错误发生,NULL。
20.4.50.3 错误
CR_COMMANDS_OUT_OF_SYNC 命令以一个不适当的次序被执行。 CR_OUT_OF_MEMORY 内存溢出。 CR_SERVER_GONE_ERROR MySQL服务器关闭了。 CR_SERVER_LOST 对服务器的连接在查询期间失去。 CR_UNKNOWN_ERROR 发生一个未知的错误。20.4.51 为什么在mysql_query()返回成功后,mysql_store_result()有时返回NULL?
有可能在一个对mysql_query()成功的调用后,mysql_store_result()返回NULL。当这发生时,它意味着出现了下列条件之一:
- 有一个malloc()失败(例如,如果结果集合太大)。
- 数据不能被读取(发生在连接上的一个错误)。
- 查询没有返回数据(例如,它是一个INSERT、UPDATE或DELETE)。
你总是可以通过调用mysql_field_count()检查语句是否应该产生非空的结果。如果mysql_field_count()返回零,结果是空的并且最后一个查询是不回值的一条语句(例如,一条INSERT或DELETE)。如果mysql_field_count()返回非零值,语句应该产生非空的结果。见对mysql_field_count()描述的一个例子。
你可以调用mysql_error()或mysql_errno()测试一个错误。
20.4.52 我能从查询中得到什么结果?
除了由查询返回的结果集合外,你也能得到下列信息:
- 当执行一条INSERT、UPDATE或DELETE时,mysql_affected_rows()返回受到最后一个查询影响的行数。一个例外是如果使用一条没有WHERE子句的DELETE,表被截断,它更快!在这种情况下,mysql_affected_rows()对于影响的记录数量返回零。
- mysql_num_rows()返回结果集合中的行数。用mysql_store_result(),一旦mysql_store_result()返回,就可以调用mysql_num_rows()。用mysql_use_result(),只有在你已经用mysql_fetch_row()取出了所有行后,才能调用mysql_num_rows()。
- mysql_insert_id()返回由将一行插入一个具有AUTO_INCREMENT索引的表中的最后查询生成的ID。见20.4.29 mysql_insert_id()。
- 某些查询(LOAD DATA INFILE ...、INSERT INTO ... SELECT ...、UPDATE)返回附加的信息。结果由返mysql_info()返回。对其返回字符串的格式,见mysql_info()的描述。如果没有附加的信息,mysql_info()返回一个NULL指针。
20.4.53 我怎样能得到最后插入的行的唯一ID?
如果你往包含一个具有AUTO_INCREMENT属性的列的一张表中插入一个记录,你能通过mysql_insert_id()函数获得最近生成的ID。
你也可以通过在你传递给mysql_query()的一个查询字符串中使用LAST_INSERT_ID()函数检索出ID。
你可以执行下列代码检查是否使用一个AUTO_INCREMENT索引。这也检查查询是否是有一个AUTO_INCREMENT索引的一条INSERT:
if (mysql_error(&mysql)[0] == 0 &&
mysql_num_fields(result) == 0 &&
mysql_insert_id(&mysql) != 0)
{
used_id = mysql_insert_id(&mysql);
}
最近产生的ID是在一个按连接的基础上在服务器上进行维护,它将不被其他客户改变。如果你更新另外一个有非奇特(non-magic)值(即一个既不是NULL也不是0的值)的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
20.4.54 链接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以包括数学库。
20.4.55 怎样制作一个线程安全的客户
客户“几乎”是线程安全的。最大的问题是在从套接字读取的“net.c”中的子程序不是中断安全的(interruot-safe)。这样做是这样考虑的,即你可能想有你自己的报警来中断一个长时间的读取服务器。
标准客户库没有用线程选项来编译。
为了获得一个线程安全的客户,使用-lmysys, -lstring和-ldbug库和服务器使用的net_serv.o。
当使用一个线程化的客户时,你可以充分利用在“thr_alarm.c”文件中的函数。如果你正在使用来自mysys库的函数,你唯一必须记住的是首先调用my_init()!
所有函数除了mysql_real_connect()目前是线程安全的。下列注意事项描述怎样编译一个线程安全的客户库并且以一种线程安全的方式使用它。(下面对mysql_real_connect()的注意事项实际上也适用于mysql_connect(),但是因为mysql_connect()不提倡使用,无论如何你应该使用mysql_real_connect()。)
为了使mysql_real_connect()是线程安全的,你必须用这个命令重新编译客户库:
shell> CPPFLAGS=-DTHREAD_SAFE_CLIENT ./configure ...
当链接标准客户时,你可能得到的某些因为未定义符号的错误,因为pthread库没有被缺省地包括。
最终的“libmysqlclient.a”库现在是线程安全的。它的含义是只要2个线程不同时查询mysql_real_connect()返回的同一个连接句柄,客户代码是线程安全的;客户机/服务器协议在一个给定的连接上一次只允许一个请求。如果你想在同一个的连接上使用多个线程,你必须在mysql_query()和mysql_store_result()调用组合附近有一个mutex锁定。一旦mysql_store_result()就绪,锁可以被释放并且其他线程可以查询同一个连接。(换句话说,不同的线程能使用不同被mysql_store_result()创建的MYSQL_RES指针,只要他们使用适当的锁定协议) 如果你用POSIX线程编程,你能使用pthread_mutex_lock()和pthread_mutex_unlock()建立并且释放一个mutex锁定。
如果你使用mysql_use_result()而不是mysql_store_result(),锁定将需要包围mysql_use_result()和mysql_fetch_row()的调用,然而,它确实对不使用mysql_use_result()线程客户是最好的。