使用C语言访问MySQL数据库基础
一、MySQL管理
包含在MySQL发行版中的一些有用的工具程序使管理工作变得相当容易。
除mysqlshow命令以外,所有的MySQL命令都接受所示的3个标准参数
命令选项 |
参数 |
说明 |
-u |
用户名 |
在默认情况下,mysql工具会尝试把当前linux的用户名作为MySQL的用户名,可以使用-u参数来指定一个不同的用户名 |
-p |
[密码] |
如果给出了-p参数但是未提供密码,系统会提示输入密码。 如果没有给出-p参数,MySQL命令将假设不需要密码 |
-h |
主机名 |
用于连接位于不同主机上的服务器(这个参数对于本地服务器总是可以省略) |
1、mysql命令
#mysql –u rick –p database-name
#mysql –u rick --password=secretpassworddatabase-name 当mysql客户端连接到服务器后,除了标准SQL92命令集外,还有以下特定命令也会被mysql支持 命令 可选的简短形式 说明 help 或? \h或\? 显示命令列表 edit \e 编辑命令。使用的编辑器由环境变量$EDITOR决定 exit或quit \q 退出MySQL客户端 Go \g 执行命令 source \. 从指定文件执行SQL Status \s 显示服务器状态信息 System \! 执行一个系统命令 tee \T 把所有文件的副本添加到指定文件中 Use \u 使用给定的数据库 每个数据库都是一个独立的表格集,这使得我们可以外对不同的目的建立不同的数据库,并为每个数据库指定不同的用户,而只需要使用同一个数据库服务器就可以有效管理它们了。 2、mysqladmin 快速进行MySQL数据库管理的主要工具 mysqladmin支持的命令 命令 说明 create 创建一个数据库 drop 删除一个数据库 Password 修改密码 Ping 检查服务器是否正在运行 reload 重载控制权限grant表 Status 提供服务器的状态 Shutdown 停止服务器 Variables 显示控制MySQL操作的变量及其当前值 Version 提供服务器的版本号以及它持续运行的时间 3、mysqldump 作用:以SQL命令集的形式将部分或整个数据库导出到一个单独文件中,该文件能被重新导入MySQL或其它的SQL RDBMS。它接受数据库名和表名作为参数 命令 说明 --add-drop-table 添加sql命令到输出文件,以在创建表的命令之前丢弃(删除)任何表 -e 使用扩展的insert语法,这不是sql标准,但是如果在正转储大量数据,那么当你试图重新加载这些数据到MySQL时,这将加速转储数据的加载速度 -t 只转储(备份)表中数据,而不是用来创建表的信息 -d 只转储(备份)表结构,而不是实际数据 例:#mysqldump –u rick –p db-name >db-name.dump 4、mysqlimport 作用:用于将批量数据导入到一个表中 通过使用mysqlimport,可以从一个输入文件中读取大量的文本数据。这个命令唯一的参数需求是一个文件名和一个数据库名。默认情况下,数据应以tab分隔符分开。 5、mysqlshow 作用:快速了解MySQL安装及其组成数据库的信息 l 不提供参数,它列出所有可用的数据库 l 以一个数据库为参数,它列出该数据库中的表 l 以数据训和表名为参数,它列出表中的列 l 以数据库、表和列为参数,它列出指定列的详细信息 二、连接例程 用C语言连接MySQL数据库包含两个步骤 l 初始化一个连接句柄结构 l 实际进行连接 1、 使用mysql_init来初始化连接句柄 #include “mysql.h” MYSQL *mysql_init(MYSQL *); 返回值:通常传递NULL给这个例程,它会返回一个指向新分配的连接句柄结构的指针 若传递一个已有的结构,它将被重新初始化。 出错时返回NULL 2、 进行实际连接 #include “mysql.h” MYSQL *mysql_real_connect(MYSQL *connection, const char*server_host,//localhost const char*sql_user_name, const char*sql_password, const char *db_name, unsigned intport_number,//端口号,一般为0 const char*unix_socket_name,//套接字,一般为null unsigned int flags); 参数:connection 必须指向已经被mysql_init初始化过的结构 Sql_user_name和sql_password如果登录名为NULL,则假设登录名为当前Linux用户的登录ID, 如果密码为NULL,将只能访问服务器上无需密码就可访问的数据,密码会在 通过网络传输前进行加密 Port_number和unix_socket_name应该分别为0和NULL flags用来对一些定义的位模式进行OR操作 返回值:若无法连接,它将返回NULL,mysql_error函数可以提供有帮助的信息 3、 关闭连接 #include “mysql.h” Void mysql_close(MYSQL *connection); 如果连接是由mysql_init建立的,MYSQL结构会被释放。指针将会失效并无法再次使用 4、 mysql_options例程 可以在mysql_init和mysql_real_connect之间调用设置一些选项 #include “mysql.h” Int mysql_options(MYSQL *connection, enum option_to_set, const char*argument); 说明:mysql_options例程一次只能设置一个选项,所以每设置一个选项就得调用它一次,同时,该例程必须出现在mysql_init和mysql_real_connect之间即可。 选 项 enum选项 实际参数类型 说明 MySQL_OPT_CONNECT_TIMEOUT Const unsigned int * 连接超时之前的等待秒数 MySQL_OPT_COMPRESS None, 使用NULL 网络连接中使用压缩机制 MySQL_INIT_COMMAND Const char * 每次连接建立后发送的命令 返回值:一次成功的调用将返回0。因为它仅仅是用来设置标志,所以失败总是意味着使用了一个无效的选项。 例:如果要设置连接超时时间为7秒,其代码片断如下: Unsigned inttimeout = 7; … connection=mysql_init(NULL); ret=mysql_option(connection,MYSQL_OPT_CONNECTION_TIMEOUT, (constchar *)&timeout); if (ret){ /Handle error */ … } connection=mysql_real_connect(connection… 5、 连接数据库实例---connect1.c 5.1 数据库部分 在211.71.149.59MySQL数据库服务器中以”ex+学号”为数据库名,以学号为用户名,创建数据库 1) 进入MySQL数据库 %mysql –u root –p Password: 1qaz2wsx 2) 生成数据库 create database ex110301; Query OK, 1 row affected (0.01sec) 3) 授权: 用户的授权信息保存于mysql数据库中的user表中 例:mysql>user mysql; mysql>select user, host, passwordfrom user; 授权语法: grant allon 数据库名.表名 to 用户名@客户登录计算机名(地址)identified by ‘密码’; 例:mysql>grant all on *.* to test@localhost identified by ‘password’; mysql>use mysql; 打开MySQL数据库 mysql>update user 更新user表 >setpassword=OLD_PASSWORD('password') >where user='test'; mysql>flush privileges; 或 mysql>grant all on ex110301.* to w12@localhost identified by ‘password’;//只能在本地访问这个数据库 mysql>grantall on ex110301.* to w12@% identified by ‘password’; (%是Any的意思,任何地方都可以访问) mysql>use mysql; 打开MySQL数据库 mysql>update user 更新user表 >setpassword=OLD_PASSWORD('password') >where user='w12'; mysql>flush privileges; 或 mysql>grant all on ex110301.* tow12@'%' identified by 'password'; mysql>use mysql; 打开MySQL数据库 mysql>update user 更新user表 >setpassword=OLD_PASSWORD('password') >where user='w12'; mysql>flush privileges; mysql>exit 4) 改用你授权的用户名/密码登录 %mysql –u 授权的用户名 -p Password:输入授权密码 5) 查看该用户有权限访问的数据库 mysql>show databases; 5.2 程序部分 1 #include 2 #include 4 #include "mysql.h" 5 6 int main(int argc, char *argv[]) { 7 MYSQL *conn_ptr; 8 9 conn_ptr = mysql_init(NULL); 10 if (!conn_ptr) { 11 fprintf(stderr, "mysql_init failed\n"); 12 return EXIT_FAILURE; 13 } 14 15 conn_ptr= mysql_real_connect(conn_ptr, "localhost", "用户名", "密码", "数据库名称", 0, NULL, 0); 18 if (conn_ptr) { 19 printf("Connection success\n"); 20 } else { 21 printf("Connection failed\n"); 22 } 23 24 mysql_close(conn_ptr); 25 26 return EXIT_SUCCESS; 27 } 编译:# gcc -I/usr/include/mysql connect1.c -L/usr/lib/mysql -lmysqlclient -o connect1 其中:-I(大写的i) 指定include路径 -L(大写的L) 指定库文件路径 -l(小写的l) 指定链接的库函数 执行:# ./connect1 结果:Connection success 三、错误处理 MySQL使用由连接句柄结构报告的返回码,两个必备的例程是: Unsigned int mysql_errno(MYSQL *connection); 返回错误码 和 char *mysql_error(MYSQL *connection); 返回错误码对应的文本信息 可以通过调用mysql_errno并传递连接结构来获得错误码(错误码在头文件errmsg.h(报告客户端错误)或mysqld_error.h(报告服务器端错误)中定义),错误码通常都是非0值。如果未设定错误码,它将返回0. 每次调用库都会更新错误码,所以只能得到最后一个执行命令的错误码。 例:connect2.c 1 #include 2 #include 4 #include "mysql.h" 5 6 int main(int argc, char *argv[]) { 7 MYSQL my_connection; 8 9 mysql_init(&my_connection); 10 if (mysql_real_connect(&my_connection, "localhost", "用户名", "错误密码", "db-name", 0, NULL, 0)) { 11 printf("Connection success\n"); 12 mysql_close(&my_connection); 13 } else { 14 fprintf(stderr, "Connection failed\n"); 15 if (mysql_errno(&my_connection)) { 16 fprintf(stderr, "Connectionerror %d: %s\n", mysql_errno(& my_connection),mysql_error(&my_connection)); 17 } 18 } 19 20 return EXIT_SUCCESS; 21 } 编译:# gcc -I/usr/include/mysql connect2.c -L/usr/lib/mysql-lmysqlclient -o connect2 执行:# ./connect2 结果:Connection failed Connection error 1045: Accessdenied for user 'n1417'@'localhost' (using password: YES)_ 四、执行SQL语句 (一)、执行SQL语句的主要API函数 Intmysql_query(MYSQL *connection, const char *query); 说明:此例程接受连接结构指针和文本字符串形式的有效SQL语句 返回值:如果成功,返回0 (二)、不返回数据的SQL语句 不返回数据SQL语句是指update, delete和insert 1、检查受影响的行数 My_ulonglongmysql_affected_rows(MYSQL *connection); 说明:返回值的数据类型是my_ulonglong(无符号长整型),使用printf时,应使用的转换符为%lu 作用:函数返回受update, insert或delete查询影响的行数 返回值:0 没有受影响的行数 正数 受语句影响的行数 1.1 操作数据库 # mysql -u 用户名 -p db-name Enter password: mysql> showtables; +---------------+ | Tables_in_foo | +---------------+ | children | +---------------+ 1 row in set (0.00sec) mysql> droptable children; 删除表children Query OK, 0 rowsaffected (0.25 sec) mysql> createtable children( 新生成children表 -> childno int(11) auto_increment notnull primary key, -> fname varchar(30), -> age int -> ); Query OK, 0 rowsaffected (0.01 sec) 插入数据 mysql> insertinto children(fname,age) values("jenny",21); mysql> insertinto children(fname,age) values("Andrew",17); mysql> insertinto children(fname,age) values("Gavin",9); mysql> insertinto children(fname,age) values("Duncan",6); mysql> insertinto children(fname,age) values("Emma",4); mysql> insertinto children(fname,age) values("Alex",15); mysql> insertinto children(fname,age) values("Ann",15); 1.2检查插入的数据 mysql> select *from children; +---------+--------+------+ | childno | fname | age | +---------+--------+------+ | 1 | jenny | 21 | | 2 | Andrew | 17 | | 3 | Gavin | 9 | | 4 | Duncan | 6 | | 5 | Emma | 4 | | 6 | Alex | 15 | | 7 | Ann | 15 | +---------+--------+------+ 7 rows in set (0.00 sec) 2、程序: 更新数据---update1.c 1 #include 2 #include 3 4 #include "mysql.h" 5 6 int main(int argc, char *argv[]) { 7 MYSQL my_connection; 8 int res; int age_value=4; 9 10 mysql_init(&my_connection); 11 if (mysql_real_connect(&my_connection, "localhost", 12 "username","secret", "foo", 0, NULL, 0)) { 13 printf("Connection success\n"); 15 res = mysql_query(&my_connection, "UPDATE children SET AGE = %d WHERE fname = 'Ann'",age_value); //说明:因为C语言不能区分一个单词是变量还是字符串,可以直接写死 //所以采用类似于printf的占位符%d,%ld,%u,%s等形式 //来明示此处引入的值是以变量形式表示。 16 if (!res) { 17 printf("Updated %lu rows\n", (unsignedlong)mysql_affected_rows(&my_connection)); 18 } else { 19 fprintf(stderr, "Update error %d: %s\n",mysql_errno(&my_co nnection), mysql_error(&my_connection)); 21 } 22 23 mysql_close(&my_connection); 24 } else { 25 fprintf(stderr, "Connection failed\n"); 26 if(mysql_errno(&my_connection)) { 27 fprintf(stderr, "Connection error%d: %s\n", mysql_errno(&my_connection),mysql_error(&my_connection)); 29 } 30 } 31 32 return EXIT_SUCCESS; 33 } 编译:# gcc -I/usr/include/mysql update1.c -L/usr/lib/mysql -lmysqlclient-o update1 执行: # ./update1 结果:未修改代码时报错 Connectionsuccess Updated1 rows 五、返回数据的语句 在C应用程序中提取数据一般需要以下4个步骤 l 执行查询:使用mysql_query来发送SQL语句 l 提取数据:使用mysql_store_result或mysql_use_result来提取数据 l 处理数据:使用mysql_fetch_row处理数据 l 必要的清理工作:使用mysql_free_result释放查询占用的资源 (一)、相关数据类型 l MYSQL_RES:此数据结构表示一次查询返回行的结果(select, show, describe, explain)。 从一查询中返回的信息被称为结果集 · MYSQL_ROW:这是一行数据的一种type-safe表示方式。它目前被作为计数字节字符串的阵列 它是由mysql_fetch_row()函数获取的行。即将一行记录中的不同类型的字段,转换为同一数据类型的数组形式,其每个属性字段的数据表达为:MYSQL_ROW[0]; MYSQL_ROW[1]; ...;MYSQL_ROW[N],避免用户定义结构体。 (二)、一次提取所有数据的函数 1、mysql_store_result() 作用:在一次调用中从select(或其它返回数据的语句)中提取所有数据,这个函数将立刻保存在客户端中返回的所有数据 #include “mysql.h” MYSQL_RES *mysql_store_result(MYSQL *connection); 说明:需要在成功调用mysql_query之后使用此函数 返回值:返回一个指向结果集结构的指针 失败则返回NULL 2、my_ulonglong mysql_num_rows(MYSQL_RES*result); 作用:在调用mysql_store_result调用成功后,需要调用mysql_num_rows来得到返回记录的数目(返回结果集中的行数) 返回值:成功 正数 如果没有返回行,这个值将是0 3、mysql_fetch_row MYSQL_ROW mysql_fetch_row(MYSQL_RES *result); 作用:这个函数从使用mysql_strore_result得到的结果结构中提取一行,并把它放到一个行结构中。 当数据用完或发生错误时返回NULL。 4、mysql_date_seek 作用:用来在结果集中跳转,设置将会被下一个msyql_fetch_row操作返回的行 Voidmysql_data_seek(MYSQL_RES *result, my_ulonglong offset); 参数:offset的值是一个行号,它必须在0到结果集总行数减1的范围内。 传递0将会导致下一个mysql_fetch_row调用返回结果集中的第一行 2、mysql_row_tell 作用:返回一个偏移值,它用来表示结果集中的当前位置。它不是行号,不能把它用于mysq_data_seek MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result); 3、mysql_free_result 作用:调用此函数来让MySQL库清理它分配的对象 Voidmysql_free_result(MYSQL_RES *result); 程序select1.c 1 #include 2 #include 3 4 #include "mysql.h" 5 6 MYSQL my_connection; 7 MYSQL_RES *res_ptr; 8 MYSQL_ROW sqlrow; 9 10 int main(int argc, char *argv[]) { 11 int res; 12 13 mysql_init(&my_connection); 14 if (mysql_real_connect(&my_connection, "localhost","rick","secret", "foo", 0, NULL, 0)) { 16 printf("Connection success\n"); 17 18 res = mysql_query(&my_connection, "SELECT childno, fname, ageFRO M children WHERE age > 5"); 19 20 if (res) { 21 printf("SELECT error: %s\n", mysql_error(&my_connection)); 22 } else { 23 res_ptr = mysql_store_result(&my_connection); 24 if (res_ptr) { 25 printf("Retrieved %lu rows\n", (unsignedlong)mysql_num_rows(res_ptr)); 26 while ((sqlrow = mysql_fetch_row(res_ptr))) { 27 printf("Fetched data...\n"); 28 } 29 if (mysql_errno(&my_connection)) { 30 fprintf(stderr, "Retrive error: %s\n",mysql_error(&my_connection)); 31 } 32 mysql_free_result(res_ptr); 33 } 35 } 36 mysql_close(&my_connection); 37 38 } else { 39 fprintf(stderr, "Connection failed\n"); 40 if (mysql_errno(&my_connection)) { 41 fprintf(stderr, "Connection error %d: %s\n", 42 mysql_errno(&my_connection), mysql_error(&my_connection)); 43 } 44 } 45 46 return EXIT_SUCCESS; 47 } 编译:cc -o select1 select1.c -I/usr/include/mysql-L/usr/lib/mysql -lmysqlclient 执行:# ./select1 结果:Connection success Retrieved 5 rows Fetched data... Fetched data... Fetched data... Fetched data... Fetched data... (三)、一次提取一行 1、逐行提取数据 MYSQL_RES*mysql_use_result(MYSQL *connection); 返回值:指向结果集对明的指针,为了真正得到数据,你必须反复调用mysql_fetch_row直到提取了所有数据。如果没有从mysql_use_result中得到所有数据,那么程序中后续的提取数据操作可能会返回遭到破坏的信息。 错误,返回NULL 2、调用mysql_use_result和mysql_store_result的区别 Mysql_use_result具备资源管理方面的实质好处,但是它不能与mysql_data_seek、mysql_row_seek或mysql_row_tell一起使用,并且由于直到所有数据都被提取后才能实际生效,mysql_num_rows的使用也受到限制。 但是它可以更好地平衡网络负载,以减少可能非常大的数据集带来的存储开销 程序:select2.c 1 #include 2 #include 3 4 #include "mysql.h" 5 6 MYSQL my_connection; 7 MYSQL_RES *res_ptr; 8 MYSQL_ROW sqlrow; 9 10 int main(int argc, char *argv[]) { 11 int res; 12 13 mysql_init(&my_connection); 14 if (mysql_real_connect(&my_connection, "localhost","rick", 15 "secret", "foo", 0, NULL, 0)) { 16 printf("Connection success\n"); 17 18 res = mysql_query(&my_connection, "SELECT childno, fname, ageFRO M children WHERE age > 5"); 19 20 if (res) { 21 printf("SELECT error: %s\n", mysql_error(&my_connection)); 22 } else { 23 res_ptr = mysql_use_result(&my_connection); 24 if (res_ptr) { 25 while ((sqlrow = mysql_fetch_row(res_ptr))) { 26 printf("Fetcheddata...\n"); 27 } 28 if (mysql_errno(&my_connection)) { 29 printf("Retrive error:%s\n", mysql_error(&my_connection)); 30 } 31 mysql_free_result(res_ptr); 32 } 33 } 34 mysql_close(&my_connection); 35 36 } else { 37 fprintf(stderr, "Connection failed\n"); 38 if (mysql_errno(&my_connection)) { 39 fprintf(stderr, "Connection error %d: %s\n", 40 mysql_errno(&my_connection), mysql_error(&my_connection)); 41 } 42 } 43 44 return EXIT_SUCCESS; 45 } 编译:# cc -o select2 select2.c -I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient 执行:./select2 Connection success Fetched data... Fetched data... Fetched data... Fetched data... Fetched data...
//不会从服务器读到客户端,所以没有提示5行 六、处理返回数据 上述函数从数据库中提取行,但是如何处理返回的实际数据呢? 同大多数SQL数据库一样,MySQL返回两种类型的数据 n 从表中提取的信息,也就是列数据 n 元数据(metadata)(describe <表名>中提取的数据) 1、mysql_field_count 作用:返回结果集中的字段(列)数目 Unsigned intmysql_field_count(MYSQL *connection); 程序select3.c 1 #include 2 #include 3 4 #include "mysql.h" 5 6 MYSQL my_connection; 7 MYSQL_RES *res_ptr; 8 MYSQL_ROW sqlrow; 9 10 void display_row(); 11 12 int main(int argc, char *argv[]) { 13 int res; 14 15 mysql_init(&my_connection); 16 if (mysql_real_connect(&my_connection, "localhost","rick","secret", "foo", 0, NULL, 0)) { 18 printf("Connection success\n"); 19 20 res = mysql_query(&my_connection, "SELECT childno, fname, ageFROM children WHERE age > 5"); 21 22 if (res) { 23 printf("SELECT error: %s\n", mysql_error(&my_connection)); 24 } else { 25 res_ptr = mysql_use_result(&my_connection); 26 if (res_ptr) { 27 while ((sqlrow = mysql_fetch_row(res_ptr))) { 28 printf("Fetcheddata...\n"); 29 display_row(); 30 } 31 if (mysql_errno(&my_connection)) { 32 printf("Retrive error:%s\n", mysql_error(&my_connection)); 33 } 34 mysql_free_result(res_ptr); 35 } 36 } 37 mysql_close(&my_connection); 38 39 } else { 40 fprintf(stderr, "Connection failed\n"); 41 if (mysql_errno(&my_connection)) { 42 fprintf(stderr, "Connection error %d: %s\n", 43 mysql_errno(&my_connection), mysql_error(&my_connection)); 44 } 45 } 46 47 return EXIT_SUCCESS; 48 } 49 50 void display_row() { 51 unsigned int field_count; 52 53 field_count = 0; 54 while (field_count < mysql_field_count(&my_connection)) { 55 printf("%s ", sqlrow[field_count]); 56 field_count++; 57 } 58 printf("\n"); 59 } 编译:# cc -o select3 select3.c -I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient 执行:# ./select3 试写出程序运行的结果: Connection success Fetched data... 1 jenny 21 Fetched data... 2 Andrew 17 Fetched data... 3 Gavin 9 Fetched data... 4 Duncan 6 Fetched data... 6 Alex 15 3、同时将元数据和数据提取到一个新的结构中 #include “mysql.h” MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result) 重复调用此函数,直到返回表示数据结束的NULL值为止,然后,使用指向字段结构数据的指针来得到关于列的信息。 结构MySQL_FIELD定义在mysql.h中 MySQL_FIELD结构中的成员 说 明 char *name; 列名,为字符串 char *table; 列所属的有名。当一个查询要使用到多个表时,非常有用 注意:对于结果中可计算的值如MAX,它所对应的表名将为空字符串 enum enum_field_types type; 列类型 unsigned int length; 列宽,在定义表时指定 unsigned int max_length; 如果使用sql_store_result,它将包含以字节为单位的提取的最长列值的长度。如果使用mysql_use_result,它将不会被设置 unsigned int flags; 关于列定义的标志,与得到的数据无关。常见标志的含义都很明显,它们是NOT_NULL_FLAG, PRI_KEY_FLAG, UNSIGNED_FLAG, AUTO_INCREMENT_FLAG和BINARY_FLAG unsigned int decimals 小数点后的数字个数,仅对数字字段有效 一个特别有用的预定义的宏为IS_NUM,当字段类型为数字时,它返回true,如 If (IS_NUM(mysql_field_ptr->type)) printf(“Numerictype filed\n”); 4、mysql_field_seek #include “mysql.h” MYSQL_FIELD_OFFSETmysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset); 作用:可以用此函数来覆盖当前的字段编号,该编号随每次mysql_fetch_field调用而自动增加 如果给参数offset传递值0,将跳回第一列 5、转义SQL语句中的特殊字符 mysql_escape_string(char *to, const char *from, unsigned long length); Mysql_real_escape_string(MYSQL *mysql, char*to, const char *from, unsigned long length) 作用:转义SQL语句中的特殊字符,用于产生一个有效的SQL字符串 参数:from : 对一个转义SQL字符串进行译码(encoded) to 将译码的结果放入to指针所指向的位置,并附加null字节 length长度 ASCII码字符转义表 例:char query[1000],*end; end = strcpy(query,"INSERTINTO test_table values("); *end++ = '\''; end +=mysql_real_escape_string(&mysql, end,"What's this",11); *end++ = '\''; *end++ = ','; *end++ = '\''; end +=mysql_real_escape_string(&mysql, end,"binary data: \0\r\n",16); *end++ = '\''; *end++ = ')'; 此时end=INSERT INTO test_table values(“what’s this” ,”binary data: “); if(mysql_real_query(&mysql,query,(unsigned int) (end - query))) { fprintf(stderr,"Failed to insert row, Error: %s\n", mysql_error(&mysql)); } 程序select4.c 1 #include 2 #include 3 4 #include "mysql.h" 5 6 MYSQL my_connection; 7 MYSQL_RES *res_ptr; 8 MYSQL_ROW sqlrow; 9 10 void display_header(); 11 void display_row(); 12 13 14 int main(int argc, char*argv[]) { 15 int res; 16 int first_row = 1; /* Used toensure we display the row header exactly once when data is successfullyretrieved */ 17 18 19 mysql_init(&my_connection); 20 if(mysql_real_connect(&my_connection, "localhost","rick","secret", "foo", 0,NULL, 0)) { 22 printf("Connectionsuccess\n"); 23 24 res = mysql_query(&my_connection,"SELECT childno, fname, ageFROM children WHERE age > 5"); 25 26 if (res) { 27 fprintf(stderr,"SELECT error: %s\n", mysql_error(&my_connection)); 28 } else { 29 res_ptr =mysql_use_result(&my_connection); 30 if (res_ptr) { 31 while ((sqlrow = mysql_fetch_row(res_ptr))) { 32 if (first_row){ 33 display_header(); 34 first_row =0; 35 } 36 display_row(); 37 } 38 if(mysql_errno(&my_connection)) { 39 fprintf(stderr,"Retrive error: %s\n", 40 mysql_error(&my_connection)); 41 } 42 mysql_free_result(res_ptr); 43 } 44 } 45 mysql_close(&my_connection); 46 } else { 47 fprintf(stderr,"Connection failed\n"); 48 if(mysql_errno(&my_connection)) { 49 fprintf(stderr,"Connection error %d: %s\n", 50 mysql_errno(&my_connection), 51 mysql_error(&my_connection)); 52 } 53 } 54 55 return EXIT_SUCCESS; 56 } 57 58 59 void display_header() { 60 MYSQL_FIELD *field_ptr; 61 62 printf("Columndetails:\n"); 63 64 while ((field_ptr =mysql_fetch_field(res_ptr)) != NULL) { 65 printf("\t Name:%s\n", field_ptr->name); 66 printf("\t Type:"); 67 if(IS_NUM(field_ptr->type)) { 68 printf("Numericfield\n"); 69 } else { 70 switch(field_ptr->type) { 71 caseFIELD_TYPE_VAR_STRING: 72 printf("VARCHAR\n"); 73 break; 74 caseFIELD_TYPE_LONG: 75 printf("LONG\n"); 76 break; 77 default: 78 printf("Type is %d, check in mysql_com.h\n",field_ptr->type); 79 } /* switch */ 80 } /* else */ 81 82 printf("\t Max width %ld\n",field_ptr->length); /* Note on versions of MySQL before 4.0 the formatshould be %d, rather than %ld */ 83 if (field_ptr->flags& AUTO_INCREMENT_FLAG) 84 printf("\t Autoincrements\n"); 85 printf("\n"); 86 } /* while */ 87 } 88 89 90 void display_row() { 91 unsigned int field_count; 92 93 field_count = 0; 94 while (field_count 95 if (sqlrow[field_count])printf("%s ", sqlrow[field_count]); 96 elseprintf("NULL"); 97 field_count++; 98 } 99 printf("\n"); 100 } 编译:# cc -o select4 select4.c -I/usr/include/mysql-L/usr/lib/mysql -lmysqlclient 执行:# ./select4 试写出程序运行的结果: Connectionsuccess Column details: Name: childno Type: Numeric field Max width 11 Auto increments Name: fname Type: VARCHAR Max width 30 Name: age Type: Numeric field Max width 11 1 jenny 21 2 Andrew 17 3 Gavin 9 4 Duncan 6 6 Alex 15