MySQL C语言API编程教程

2019年12月11日 阅读数:203
这篇文章主要向大家介绍MySQL C语言API编程教程,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。


http://www.xftalk.com/archives/474
mysql

本篇教程使用C语言进行MySql数据库编程,内容覆盖了基本的使用C语言API进行MySql编程。本教程的程序在Ubuntu下进行编写和编译运行。为了可以使用C语言进行MySql数据库编程,咱们须要安装MySQL的C开发库。sql

在基于Debian的Linux中开发库的安装命令以下。
sudo apt-get install libmysqlclient-dev数据库

MySQL的安装命令以下,安装过程当中咱们须要给root帐号设定密码。
sudo apt-get install mysql-server编程

第一个例子

在第一个例子中,咱们测试一个MySQL函数的调用。ubuntu

1
2
3
4
5
6
7
8
9
#include<my_global.h>
#include<mysql.h>
 
int main( int argc, char **argv)
{
         printf ( "MySQL client version: %s\n" ,mysql_get_client_info());
         return 0;
 
}

mysql_get_client_info()函数显示MySQL客户端版本。数组

1
2
#include<my_global.h>
#include<mysql.h>

这两行包含必要的头文件。mysql.h 是MySQL函数调用中最重要的头文件。my_global.h 包含一些全局函数的声明,除此以外,它还包含一些标准的输入/输出头文件。服务器

1
gcc version.c -o version `mysql_config --cflags --libs`

在终端中输入该命令编译源代码文件。socket

除此以外,还有另外一种编译方法。个人MySQL头文件安装目录为/usr/include/mysql/,库文件安装在/usr/lib/目录下,程序须要使用的库名称为libmysqlclient.so,所以另外一种编译方法以下。固然,熟悉Linux编程的,咱们能够将编译命令写到Makefile文件,这样不用每次都敲这些长长的编译命令了,直接一个make命令就可搞定了。ide

1
gcc version.c -o version -I/usr/include/include/ -lmysqlclient
1
2
ubuntu-root#./version
MySQL client version: 5.1.63

运行程序,在终端打印输出结果。函数

建立数据库

下面的程序将要建立一个数据库。程序的内容能够分为四个部分。

  • 初始化数据库链接句柄结构
  • 建立数据库链接
  • 执行一个查询语句
  • 关闭数据库链接
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
#include<my_global.h>
#include<mysql.h>
 
int main( int argc, char **argv)
{
         MYSQL *con = mysql_init(NULL);
         if (NULL == con)
         {
                 fprintf (stderr, "%s\n" ,mysql_error(con));
                 return -1;
         }
         if (NULL == mysql_real_connect(con, "localhost" , "root" , "123456" ,NULL,0,NULL,0))
         {
                 fprintf (stderr, "%s\n" ,mysql_error(con));
                 mysql_close(con);
                 return -1;
         }
         if (mysql_query(con, "CREATE DATABASE mydb" ))
         {
                 fprintf (stderr, "%s\n" ,mysql_error(con));
                 mysql_close(con);
                 return -1;
         }
         fprintf (stdout, "%s\n" ,mysql_get_server_info(con));
         fprintf (stdout, "%s\n" ,mysql_get_host_info(con));
 
         mysql_close(con);
        return 0;
}

这个例子演示了如何链接MySQL数据库系统并建立一个数据库mydb。

1
MYSQL *con = mysql_init(NULL);

mysql_init()函数分配或初始化一个MYSQL对象,该对象mysql_real_connect()函数链接数据库时须要使用。

1
2
3
4
5
if (con == NULL)
{
     fprintf (stderr, "%s\n" , mysql_error(con));
     return -1;
}

经过检查mysql_init()函数的返回值肯定初始化对象是否成功。若是失败,程序绘制终端打印错误信息并终止运行。

1
2
3
4
5
6
7
if (mysql_real_connect(con, "localhost" , "root" , "123456" ,
         NULL, 0, NULL, 0) == NULL)
{
     fprintf (stderr, "%s\n" , mysql_error(con));
     mysql_close(con);
     exit (1);
}

mysql_real_connect()函数创建一个指向数据库的链接。咱们须要指定链接句柄,主机名,数据库帐号和用户密码。函数最后四个参数是数据库名,端口号,unix套接字和客户端标记。咱们须要超级用户权限来建立新的数据库。

1
2
3
4
5
6
if (mysql_query(con, "CREATE DATABASE mydb" ))
{
     fprintf (stderr, "%s\n" , mysql_error(con));
     mysql_close(con);
     exit (1);
}

mysql_query()函数执行一个SQL语句。语句"CREATE DATABASE mydb"用于建立一个新的数据库mydb。
mysql_get_server_info()mysql_get_host_info()函数分别获取服务器和主机信息。

1
mysql_close(con);

程序结束或出现异常前须要关闭数据库链接。最后,编译和运行程序,方法和第一个例子同样。

1
2
3
4
5
6
7
8
9
10
11
12
13
ubuntu-root#./createdb
5.1.63-0ubuntu0.11.04.1
Localhost via UNIX socket
 
mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mydb               |
| mysql              |
+--------------------+
3 rows in set (0.00 sec)

从上面显示结果来看,多了一个mydb数据库,这就是咱们经过程序来建立的。

建立表并填充数据

在建立一张新的数据库表前,咱们须要建立一个接下来须要使用的帐号。

1
2
mysql> CREATE USER user123@localhost IDENTIFIED BY '123456' ;
mysql> GRANT ALL ON mydb.* to user123@localhost;

上面咱们建立了一个新的数据库帐号user123,密码为123456。同时咱们将mydb数据库的全部权限授予user123。

接下来的例子咱们为mydb数据库建立一张新表并向表中插入数据。

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
#include<my_global.h>
#include<mysql.h>
 
int finish_with_error(MYSQL *con)
{
         fprintf (stderr, "%s\n" ,mysql_error(con));
         mysql_close(con);
         return -1;
}
 
int main( int argc, char **argv)
{
         MYSQL *con = mysql_init(NULL);
         if (NULL == con)
         {
                 fprintf (stderr, "%s\n" ,mysql_error(con));
                 return -1;
         }
         if (NULL == mysql_real_connect(con, "localhost" , "user123" , "123456" , "mydb" ,0,NULL,0))
         {
                 finish_with_error(con);
         }
         if (mysql_query(con, "DROP TABLE IF EXISTS Phones" ))
         {
                 finish_with_error(con);
         }
         if (mysql_query(con, "CREATE TABLE Phones(Id INT,Name TEXT,Price INT)" ))
         {
                 finish_with_error(con);
         }
         if (mysql_query(con, "INSERT INTO Phones VALUES(1,'三星GALAXY S4',5199)" ))
         {
                 finish_with_error(con);
         }
         if (mysql_query(con, "INSERT INTO Phones VALUES(2,'苹果iPhone5',5200)" ))
         {
                 finish_with_error(con);
         }
         if (mysql_query(con, "INSERT INTO Phones VALUES(3,'联想K900',3299)" ))
         {
                 finish_with_error(con);
         }
         if (mysql_query(con, "INSERT INTO Phones VALUES(4,'三星GALAXY Note II N7100(16GB)',4699)" ))
         {
                 finish_with_error(con);
         }
         if (mysql_query(con, "INSERT INTO Phones VALUES(5,'华硕PadFone2',4999)" ))
         {
                 finish_with_error(con);
         }
         if (mysql_query(con, "INSERT INTO Phones VALUES(6,'诺基亚920',2900)" ))
         {
                 finish_with_error(con);
         }
         if (mysql_query(con, "INSERT INTO Phones VALUES(7,'三星GALAXY SIII',3470)" ))
         {
                 finish_with_error(con);
         }
         if (mysql_query(con, "INSERT INTO Phones VALUES(8,'苹果iPhone 4S',4700)" ))
         {
                 finish_with_error(con);
         }
         if (mysql_query(con, "INSERT INTO Phones VALUES(9,'HTC One',4480)" ))
         {
                 finish_with_error(con);
         }
         if (mysql_query(con, "INSERT INTO Phones VALUES(10,'索尼L36H(Xperia Z)',3800)" ))
         {
                 finish_with_error(con);
         }
         mysql_close(con);
         return 0;
}

这个例子中咱们使用mysql_query()函数建立一个表并向表中插入数据。

1
2
3
4
5
if (mysql_real_connect(con, "localhost" , "user123" , "123456" ,
         "mydb" , 0, NULL, 0) == NULL)
{
     finish_with_error(con);
}  

链接数据库mydb。用户名和密码是user123和123456。第五个参数是要链接的数据库名。

1
2
3
if (mysql_query(con, "CREATE TABLE Phones(Id INT, Name TEXT, Price INT)" )) {     
     finish_with_error(con);
}

建立表Phones。它由三个列:Id,Name和Price,类型分别为INT,TEXT和INT。

1
2
3
4
if (mysql_query(con, "INSERT INTO Phones VALUES(1,'三星GALAXY S4',5199)" ))
{
     finish_with_error(con);
}

向Phones表中插入一行数据。程序中一共向表中插入了10行数据,这里咱们选取了最近热销的前10款智能手机名称及其网上报价。
程序编译、运行后,咱们能够查看数据库中的内容。

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
mysql> USE mydb;
Database changed
mysql> SHOW TABLES;
+----------------+
| Tables_in_mydb |
+----------------+
| Phones         |
+----------------+
1 row in set (0.00 sec)
 
mysql> SELECT * FROM Phones;
+------+----------------------------------+-------+
| Id   | Name                             | Price |
+------+----------------------------------+-------+
|    1 | 三星GALAXY S4                  |  5199 |
|    2 | 苹果iPhone5                    |  5200 |
|    3 | 联想K900                       |  3299 |
|    4 | 三星GALAXY Note II N7100(16GB) |  4699 |
|    5 | 华硕PadFone2                   |  4999 |
|    6 | 诺基亚920                     |  2900 |
|    7 | 三星GALAXY SIII                |  3470 |
|    8 | 苹果iPhone 4S                  |  4700 |
|    9 | HTC One                          |  4480 |
|   10 | 索尼L36H(Xperia Z)             |  3800 |
+------+----------------------------------+-------+
10 rows in set (0.00 sec)

咱们查看了数据库mydb中全部的表并从Phones表中选择了全部数据进行显示。显示内容和程序中插入数据的内容是同样的。

从表中获取数据

接下来的例子,咱们要从表中获取数据。

步骤
1
2
3
4
5
建立链接
执行查询语句
获取查询结果集
取出全部可用的行数据
释放结果集
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
#include<my_global.h>
#include<mysql.h>
 
int finish_with_error(MYSQL *con)
{
         fprintf (stderr, "%s\n" ,mysql_error(con));
         mysql_close(con);
         return -1;
}
 
int main( int argc, char **argv)
{
         MYSQL *con = mysql_init(NULL);
         if (NULL == con)
         {
                 fprintf (stderr, "%s\n" ,mysql_error(con));
                 return -1;
         }
         if (NULL == mysql_real_connect(con, "localhost" , "user123" , "123456" , "mydb" ,0,NULL,0))
         {
                 finish_with_error(con);
         }
         if (mysql_query(con, "SELECT * FROM Phones" ))
         {
                 finish_with_error(con);
         }
         MYSQL_RES *result = mysql_store_result(con);
         if (NULL == result)
         {
                 finish_with_error(con);
         }
         int num_fields = mysql_num_fields(result);
         MYSQL_ROW row;
         while ((row = mysql_fetch_row(result)))
         {
                 for ( int i = 0;i < num_fields;i++)
                 {
                         printf ( "%s " ,row[i] ? row[i] : "NULL" );
                 }
                 printf ( "\n" );
         }
 
         mysql_free_result(result);
         mysql_close(con);
         return 0;
}

本例打印表Phones中全部列的内容。

1
2
3
4
if (mysql_query(con, "SELECT * FROM Phones" ))
{
     finish_with_error(con);
}

执行SQL语句,该语句从Phones表中获取全部数据。

1
MYSQL_RES *result = mysql_store_result(con);

使用mysql_store_result()函数获取结果集。MYSQL_RES是一个保存结果集的结构体。

1
int num_fields = mysql_num_fields(result);

获取表中字段(列)的个数。

1
2
3
4
5
6
7
8
while ((row = mysql_fetch_row(result)))
{
     for ( int i = 0; i < num_fields; i++)
     {
         printf ( "%s " , row[i] ? row[i] : "NULL" );
     }
     printf ( "\n" );
}

遍历结果集取出每行数据并在终端打印出来。

1
2
mysql_free_result(result);
mysql_close(con);

这里程序的编译须要加上-std=c99选项,不然代码中有些写法不支持,程序编译不过。

1
gcc -o retrieva_data retrieva_data.c  -std=c99 `mysql_config --cflags --libs`

释放资源。

运行结果:
1
2
3
4
5
6
7
8
9
10
1 三星GALAXY S4 5199
2 苹果iPhone5 5200
3 联想K900 3299
4 三星GALAXY Note II N7100(16GB) 4699
5 华硕PadFone2 4999
6 诺基亚920 2900
7 三星GALAXY SIII 3470
8 苹果iPhone 4S 4700
9 HTC One 4480
10 索尼L36H(Xperia Z) 3800

最后插入行的id

有些时候,咱们须要肯定最后插入一行的id。经过调用mysql_insert_id()函数,咱们能够肯定最后插入一行的id。这个函数只有在咱们在表中定义了一个具备AUTO_INCREMENT自增特性的列时才会生效。

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
#include<my_global.h>
#include<mysql.h>
 
int finish_with_error(MYSQL *con)
{
         fprintf (stderr, "%s\n" ,mysql_error(con));
         mysql_close(con);
         return -1;
}
 
int main( int argc, char **argv)
{
         MYSQL *con = mysql_init(NULL);
         if (NULL == con)
         {
                 fprintf (stderr, "%s\n" ,mysql_error(con));
                 return -1;
         }
         if (NULL == mysql_real_connect(con, "localhost" , "user123" , "123456" , "mydb" ,0,NULL,0))
         {
                 finish_with_error(con);
         }
         if (mysql_query(con, "DROP TABLE IF EXISTS Writers" ))
         {
                 finish_with_error(con);
         }
         char *sql = "CREATE TABLE Writers(Id INT PRIMARY KEY AUTO_INCREMENT,Name TEXT)" ;
         if (mysql_query(con,sql))
         {
                 finish_with_error(con);
         }
         if (mysql_query(con, "INSERT INTO Writers(Name) VALUES('易中天')" ))
         {
                 finish_with_error(con);
         }
         if (mysql_query(con, "INSERT INTO Writers(Name) VALUES('于丹')" ))
         {
                 finish_with_error(con);
         }
         if (mysql_query(con, "INSERT INTO Writers(Name) VALUES('纪连海')" ))
         {
                 finish_with_error(con);
         }
         int id = mysql_insert_id(con);
         printf ( "最后插入行的id是: %d\n" ,id);
         mysql_close(con);
         return 0;
}

本例建立了一个新表Writers。表中将会插入三行的数据,咱们肯定最后一行的id。

1
char *sql = "CREATE TABLE Writers(Id INT PRIMARY KEY AUTO_INCREMENT, Name TEXT)" ;

建立新表的SQL语句,其中Id列具备AUTO_INCREMENT类型。

1
int id = mysql_insert_id(con);

mysql_insert_id()返回由先前的INSERT或UPDATE语句为具备AUTO_INCREMENT属性的列生成的一个值。

运行结果
1
最后插入行的id是: 3

列标题

下面的例子,咱们要从表中获取数据和对于的列标题。

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
#include<my_global.h>
#include<mysql.h>
 
int finish_with_error(MYSQL *con)
{
         fprintf (stderr, "%s\n" ,mysql_error(con));
         mysql_close(con);
         return -1;
}
 
int main( int argc, char **argv)
{
         MYSQL *con = mysql_init(NULL);
         if (NULL == con)
         {
                 fprintf (stderr, "%s\n" ,mysql_error(con));
                 return -1;
         }
         if (NULL == mysql_real_connect(con, "localhost" , "user123" , "123456" , "mydb" ,0,NULL,0))
         {