通过C语言的API连接MySQL数据库
一、如何连接MySQL
C的API文档地址:https://www.mysqlzh.com/doc/194.html
首先需要安装MySQL
1 2 | sudo apt-get update sudo apt-get install mysql-server |
C语言的API代码是与MySQL一起提供的,它包含在mysqlclient库中,并允许C程序访问数据库,如果安装MySQL后仍提示缺少库,则需要安装如下:
1 2 | sudo apt-get install libmysqlclient-dev sudo apt-get install libmysql++-dev |
与MySQL交互时,应用程序应使用以下步骤:
- 通过调用mysql_library_init(),初始化MySQL库。库可以是mysqlclient C客户端,或mysqld嵌入式服务器库,具体情况取决于应用程序是否与"-libmysqlclient"或"-libmysqld"标志连接。
- 通过调用mysql_init()初始化连接处理程序,并通过调用mysql_connect()连接到服务器。
- 发出SQL语句并处理其结果。
- 通过调用mysql_close(),关闭于MySQL服务器的连接。
- 通过调用mysql_library_end(),结束MySQL库的使用。
调用mysql_library_init()和mysql_library_end()的目的在于为MySQL库提供恰当的初始化和结束处理。对于与客户端库链接的应用程序,它们提供了改进的内存管理功能,如果不调用mysql_library_end(),内存块仍将保持分配状态(这不会增加应用程序的内存量,但某些内存泄漏器将会抗议它)。对于与嵌入式服务器链接的应用程序,这些调用会启动并停止服务器。mysql_library_init()和mysql_library_end()实际上是#define符号,这类符号使得它们等效于mysql_server_init()和mysql_server_end(),但其名称更清楚地指明,无论应用程序使用的mysqkclient或mysqld库,启动或结束MySQ库时,应用调用它们。对于早期的MySQL版本,可调用mysql_server_init()和mysql_server_end()取而代之。如果愿意,可省略对mysql_library_init()的调用,这是因为,必要时,mysql_init()会自动调用它。
二、相关函数介绍
1.mysql_init()
1 | MYSQL *STDCALL mysql_init(MYSQL *mysql); |
描述:分配或初始化与mysql_real_connect()相适应的MYSQL对象,如果mysql是NULL指针,该函数将分配、初始化、并返回新对象。否则,将初始化对象,并返回对象的地址,如果mysql_init()分配了新的对象,当调用mysql_close()来关闭连接时,将释放该对象。
返回值:初始化的MYSQL*句柄,如果无足够的内存以分配新的对象,返回NULL。
错误:在内存不足的情况下,返回NULL。
2.mysql_close()
1 | void STDCALL mysql_close(MYSQL *sock); |
描述:关闭前面打开的连接,如果句柄是由mysql_init()或mysql_connect()自动分配的,mysql_close()还将解除分配由mysql指向的连接句柄。
3.mysql_real_connect()
1 | MYSQL *STDCALL mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long clientflag); |
描述:mysql_real_connect()尝试与运行在主机上的MySQL数据库引擎建立连接,在能够执行需要有效MySQL连接句柄结构的任何其他API函数之前,所有mysql_real_connect()必须成功完成。
参数的指定方式如下:
- mysql:已有的MYSQL结构的地址,调用mysql_real_connect()之前,必须调用mysql_init()来初始化MYSQL结构。通过mysql_option()调用,可更改连接选项。
- host:必须是主机名或IP地址,如果host是NULL或字符串"localhost",连接将被视为与本地主机的连接。
- user:包含用户的MySQL登录ID,如果user是NULL或空字符串"",用户将被视为当前用户。在UNIX环境下,它是当前的登陆名。
- passwd:包含用户的密码,如果passwd是NULL,仅会对该用户的(拥有1个空密码字段的)用户表中的条目进行匹配检查。这样,数据库管理员就能按特定的方式设置MySQL权限系统,根据用户是否拥有指定的密码,用户将获得不同的权限。
- db:是数据库名称,如果db为NULL,连接会将默认的数据库设为该值。
- port:如果port不是0,其值将用于TCP/IP连接的端口号,注意,"host"参数决定了连接的类型。
- unix_socket:如果值不是NULL,该字符串描述了应使用的套接字或命名管道,注意,"host"参数决定了连接的类型。
- clientflag:值通常为0。
对于某些参数,能够从选项文件获得取值,而不是取得mysql_real_connect()调用中的确切值,为此,在调用mysql_real_connect()之前,应与MYSQL_READ_DEFAULT_FILE或MYSQL_READ_DEFAULT_GROUP选项一起调用mysql_option()。随后,在mysql_real_connect()调用中,为准备选项文件读取值的每个参数指定"无值"值。
- 对于host,指定NULL值或空字符串("")。
- 对于user,指定NULL值或空字符串。
- 对于passwd,指定NULL值。(对于密码,调用中的空字符串的值不能被选项文件中的字符串覆盖,这是因为空字符串明确指明MySQL账户必须由空密码)。
- 对于db,指定NULL值或空字符串。
- 对于port,指定"0"值。
- 对于unix_socket,指定NULL值
对于某一参数,如果在选项文件中未发现值,将使用它的默认值。
返回值:如果连接成功,返回MYSQL*连接句柄,如果连接失败,返回NULL,对于成功的连接,返回值与第一个参数的值相同。
错误:
- CR_CONN_HOST_ERROR:无法连接到MySQL服务器。
- CR_CONNECTION_ERROR:无法连接到本地MySQL服务器。
4.mysql_query()
1 | int mysql_query(MYSQL *mysql, const char *query); |
描述:
执行由“Null终结的字符串”查询指向的SQL查询。正常情况下,字符串必须包含1条SQL语句,而且不应为语句添加终结分号(‘;’)或“\g”。如果允许多语句执行,字符串可包含多条由分号隔开的语句。mysql_query()不能用于包含二进制数据的查询,应使用mysql_real_query()取而代之(二进制数据可能包含字符‘\0’,mysql_query()会将该字符解释为查询字符串结束)。如果希望了解查询是否应返回结果集,可使用mysql_field_count()进行检查。
返回值:
如果查询成功,返回0。如果出现错误,返回非0值。
5.mysql_real_query()
1 | int mysql_real_query(MYSQL *mysql, const char *query, unsigned long length); |
描述:
执行由“query”指向的SQL查询,它应是字符串长度字节“long”。正常情况下,字符串必须包含1条SQL语句,而且不应为语句添加终结分号(‘;’)或“\g”。如果允许多语句执行,字符串可包含由分号隔开的多条语句。“多查询执行的C API处理”。对于包含二进制数据的查询,必须使用mysql_real_query()而不是mysql_query(),这是因为,二进制数据可能会包含‘\0’字符。此外,mysql_real_query()比mysql_query()快,这是因为它不会在查询字符串上调用strlen()。
返回值:如果查询成功,返回0,如果出现错误,返回非0值。
6.mysql_error()
1 | const char *mysql_error(MYSQL *mysql); |
描述:对于由mysql指定的连接,对于失败的最近调用的API函数,mysql_error()返回包含错误消息的、由Null终结的字符串。如果该函数未失败,mysql_error()的返回值可能是以前的错误,或指明无错误的空字符串。
返回值:返回描述错误的、由Null终结的字符串。如果未出现错误,返回空字符串。
7.mysql_store_result()
1 | MYSQL_RES *mysql_store_result(MYSQL *mysql); |
描述:
对于成功检索了数据的每个查询(SELECT、SHOW、DESCRIBE、EXPLAIN、CHECK TABLE等),必须调用mysql_store_result()或mysql_use_result() 。mysql_store_result()将查询的全部结果读取到客户端,分配1个MYSQL_RES结构,并将结果置于该结构中。如果查询未返回结果集,mysql_store_result()将返回Null指针(例如,如果查询是INSERT语句)。如果读取结果集失败,mysql_store_result()还会返回Null指针。通过检查mysql_error()是否返回非空字符串。一旦调用了mysql_store_result()并获得了不是Null指针的结果,可调用mysql_num_rows()来找出结果集中的行数。一旦完成了对结果集的操作,必须调用mysql_free_result()。
返回值:具有多个结果的MYSQL_RES结果集合。如果出现错误,返回NULL。
8.mysql_num_rows()
1 | my_ulonglong mysql_num_rows(MYSQL_RES *result); |
描述:返回结果集中的行数。mysql_num_rows()的使用取决于是否采用了mysql_store_result()或mysql_use_result()来返回结果集。如果使用了mysql_store_result(),可以立刻调用mysql_num_rows()。如果使用了mysql_use_result(),mysql_num_rows()不返回正确的值,直至检索了结果集中的所有行为止。
返回值:结果集中的行数。
9.mysql_num_fields()
1 | unsigned int mysql_num_fields(MYSQL_RES *result); |
返回值:结果集的列数。
10.mysql_fetch_row()
1 | MYSQL_ROW mysql_fetch_row(MYSQL_RES *result) ; |
描述:
检索结果集的下一行。在mysql_store_result()之后使用时,如果没有要检索的行,mysql_fetch_row()返回NULL。在mysql_use_result()之后使用时,如果没有要检索的行或出现了错误,mysql_fetch_row()返回NULL。行内值的数目由mysql_num_fields(result)给出。如果行中保存了调用mysql_fetch_row()返回的值,将按照row[0]到row[mysql_num_fields(result)-1],访问这些值的指针。行中的NULL值由NULL指针指明。可以通过调用mysql_fetch_lengths()来获得行中字段值的长度。对于空字段以及包含NULL的字段,长度为0。通过检查字段值的指针,能够区分它们。如果指针为NULL,字段为NULL,否则字段为空。
返回值:下一行的MYSQL_ROW结构。如果没有更多要检索的行或出现了错误,返回NULL。
11.mysql_fetch_lengths()
1 | unsigned long *mysql_fetch_lengths(MYSQL_RES *result) |
描述:返回结果集内当前行的列的长度。如果打算复制字段值,该长度信息有助于优化,这是因为,你能避免调用strlen()。此外,如果结果集包含二进制数据,必须使用该函数来确定数据的大小,原因在于,对于包含Null字符的任何字段,strlen()将返回错误的结果。对于空列以及包含NULL值的列,其长度为0。
返回值:无符号长整数的数组表示各列的大小(不包括任何终结NULL字符)。如果出现错误,返回NULL。
12.mysql_fetch_fields()
1 | MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result); |
描述:对于结果集,返回所有MYSQL_FIELD结构的数组。每个结构提供了结果集中1列的字段定义。
返回值:关于结果集所有列的MYSQL_FIELD结构的数组。
三、执行插入、删除、修改等SQL语句
示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | #include <stdio.h> #include <stdlib.h> #include <string.h> #include <mysql/mysql.h> #define HOST_IP "localhost" #define USER_NAME "root" #define USER_PWD "root" #define DB_NAME "mydb" int main() { MYSQL *mysql = NULL; //初始化 mysql = mysql_init(NULL); if (mysql == NULL) { printf ( "mysql_init failde...\n" ); return -1; } printf ( "mysql_init successfully...\n" ); //连接数据库 mysql = mysql_real_connect(mysql, HOST_IP, USER_NAME, USER_PWD, DB_NAME, 0, NULL, 0); if (mysql == NULL) { printf ( "mysql_real_connect failed:%s\n" , mysql_error(mysql)); return -1; } printf ( "mysql_real_connect successfully...\n" ); char buffer[128] = {0}; //插入数据 strncpy (buffer, "insert into student(id,name,chinese,english,math) values(11,'张三',93,95,91)" , sizeof (buffer)); int ret = mysql_query(mysql, buffer); if (ret != 0) { printf ( "mysql_query insert failed:%s\n" , mysql_error(mysql)); mysql_close(mysql); return -1; } printf ( "insert data successfully...\n" ); memset (buffer, 0, sizeof (buffer)); //删除数据 strncpy (buffer, "delete from student where id=1" , sizeof (buffer)); ret = mysql_query(mysql, buffer); if (ret != 0) { printf ( "mysql_query delete failed:%s\n" , mysql_error(mysql)); mysql_close(mysql); return -1; } printf ( "delete data successfully...\n" ); memset (buffer, 0, sizeof (buffer)); //修改数据 strncpy (buffer, "update student set name='范冰冰' where id=4" , sizeof (buffer)); ret = mysql_query(mysql, buffer); if (ret != 0) { printf ( "mysql_query update failed:%s\n" , mysql_error(mysql)); mysql_close(mysql); return -1; } printf ( "update data successfully...\n" ); //关闭连接 mysql_close(mysql); return 0; } |
四、执行select语句并输出结果
示例如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | #include <stdio.h> #include <stdlib.h> #include <string.h> #include <mysql/mysql.h> #define HOST_IP "localhost" #define USER_NAME "root" #define USER_PWD "root" #define DB_NAME "mydb" int main() { MYSQL *mysql = NULL; MYSQL_RES *res = NULL; MYSQL_ROW row = NULL; unsigned int i; //初始化 mysql = mysql_init(NULL); if (mysql == NULL) { printf ( "mysql_init failde...\n" ); return -1; } printf ( "mysql_init successfully...\n" ); //连接数据库 mysql = mysql_real_connect(mysql, HOST_IP, USER_NAME, USER_PWD, DB_NAME, 0, NULL, 0); if (mysql == NULL) { printf ( "mysql_real_connect failed:%s\n" , mysql_error(mysql)); return -1; } printf ( "mysql_real_connect successfully...\n" ); char buffer[128] = {0}; //执行select语句 strncpy (buffer, "select * from student" , sizeof (buffer)); int ret = mysql_query(mysql, buffer); if (ret != 0) { printf ( "mysql_query failed:%s\n" , mysql_error(mysql)); mysql_close(mysql); return -1; } //获取结果集 res = mysql_store_result(mysql); if (res == NULL) { printf ( "mysql_store_result failed:%s\n" , mysql_error(mysql)); mysql_close(mysql); return -1; } printf ( "mysql_store_result successfully...\n" ); //获取结果集中的行数 printf ( "row:%lu\n" , mysql_num_rows(res)); //获取结果集中的列数 printf ( "column:%u\n" , mysql_num_fields(res)); //获取字段数量 unsigned int num_fields = mysql_num_fields(res); //获取字段信息 MYSQL_FIELD *fields = mysql_fetch_fields(res); while (1) { unsigned int flag = 0; row = mysql_fetch_row(res); if (row == NULL) { break ; } for (i = 0; i < num_fields; i++) { flag++; printf ( "%s:%s " , fields[i].name, row[i] ? row[i] : "NULL" ); if (flag == num_fields) { printf ( "\n" ); } } } printf ( "\n" ); //释放结果集 mysql_free_result(res); //关闭连接 mysql_close(mysql); return 0; } |
数据表数据显示:
查询结果显示:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· DeepSeek “源神”启动!「GitHub 热点速览」
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器