MySQL C语言API编程教程

第一个例子

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

1

2

3

4

5

6

7

8

9

#include<my_global.h>

#include<mysql.h>

intmain(intargc,char**argv)

{

printf("MySQL client version: %s\n",mysql_get_client_info());

return0;

}

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`

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

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

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>

intmain(intargc,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);

return0;

}

这个例子演示了如何连接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>

intfinish_with_error(MYSQL *con)

{

fprintf(stderr,"%s\n",mysql_error(con));

mysql_close(con);

return-1;

}

intmain(intargc,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);

return0;

}

这个例子中我们使用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>

intfinish_with_error(MYSQL *con)

{

fprintf(stderr,"%s\n",mysql_error(con));

mysql_close(con);

return-1;

}

intmain(intargc,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);

}

intnum_fields = mysql_num_fields(result);

MYSQL_ROW row;

while((row = mysql_fetch_row(result)))

{

for(inti = 0;i < num_fields;i++)

{

printf("%s ",row[i] ? row[i] :"NULL");

}

printf("\n");

}

mysql_free_result(result);

mysql_close(con);

return0;

}

本例打印表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

intnum_fields = mysql_num_fields(result);

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

1

2

3

4

5

6

7

8

while((row = mysql_fetch_row(result)))

{

for(inti = 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>

intfinish_with_error(MYSQL *con)

{

fprintf(stderr,"%s\n",mysql_error(con));

mysql_close(con);

return-1;

}

intmain(intargc,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);

}

intid = mysql_insert_id(con);

printf("最后插入行的id是: %d\n",id);

mysql_close(con);

return0;

}

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

1

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

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

1

intid = 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>

intfinish_with_error(MYSQL *con)

{

fprintf(stderr,"%s\n",mysql_error(con));

mysql_close(con);

return-1;

}

intmain(intargc,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 LIMIT 5"))

{

finish_with_error(con);

}

MYSQL_RES *result = mysql_store_result(con);

if(NULL == result)

{

finish_with_error(con);

}

intnum_fields = mysql_num_fields(result);

MYSQL_ROW row;

MYSQL_FIELD *field;

while((row = mysql_fetch_row(result)))

{

for(inti = 0;i < num_fields;i++)

{

if(0 == i)

{

while(field = mysql_fetch_field(result))

{

printf("%s ",field->name);

}

printf("\n");

}

printf("%s ",row[i]?row[i]:NULL);

}

}

printf("\n");

mysql_free_result(result);

mysql_close(con);

return0;

}

我们在终端打印表Phones前五行的数据,包括每列的标题名。

MYSQL_FIELD是一个包含字段信息的结构体,比如字段的名称,类型和大小等。字段对应的值不在该结构体中,它们包含在MYSQL_ROW结构体中。

1

2

3

4

5

6

7

8

9

if(i == 0)

{

while(field = mysql_fetch_field(result))

{

printf("%s ", field->name);

}

printf("\n");

}

第一行包含列标题。mysql_fetch_field()函数返回MYSQL_FIELD结构体。我们从该结构体中获取列标题的名称。

运行结果:

1

2

3

4

5

6

Id Name Price

1 三星GALAXY S4 5199

2 苹果iPhone5 5200

3 联想K900 3299

4 三星GALAXY Note II N7100(16GB) 4699

5 华硕PadFone2 4999

多语句

我们可以在一次查询中执行多个SQL语句。我们需要在连接方法中设置CLIENT_MULTI_STATEMENTS标记。

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

#include<my_global.h>

#include<mysql.h>

intfinish_with_error(MYSQL *con)

{

fprintf(stderr,"%s\n",mysql_error(con));

mysql_close(con);

return-1;

}

intmain(intargc,char**argv)

{

intstatus = 0;

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,CLIENT_MULTI_STATEMENTS))

{

finish_with_error(con);

}

if(mysql_query(con,"SELECT Name FROM Phones WHERE Id = 3;\

SELECT Name FROM Phones WHERE Id = 4;SELECT Name FROM Phones WHERE ))

{

finish_with_error(con);

}

do

{

MYSQL_RES *result = mysql_store_result(con);

if(NULL == result)

{

finish_with_error(con);

}

MYSQL_ROW row = mysql_fetch_row(result);