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))
         {
相關文章
相關標籤/搜索