1. 程式人生 > >Linux程式設計——C語言連線MySQL資料庫

Linux程式設計——C語言連線MySQL資料庫

MySQL是Linux系統下廣泛使用的開源免費資料庫,是Linux應用程式資料儲存的首選。許多釋出的Linux版本是自帶MySQL的,但是也有些釋出版本是不帶的(比如我現在用的Ubuntu),那就需要手動安裝。在Synaptic Packet Management中搜索“mysql”,可以找到“mysql-client"包,點選安裝即可。

安裝好的MySQL是在命令列下執行的,這對於許多經常在Windows下開發程式,習慣使用圖形化工具的人來說是很痛苦的。因此我們需要 安裝MySQL圖形化管理工具MySQL Administrator和MySQL Query Brower。開啟Ubuntu Software Center,輸入”mysql"搜尋,可以看到這兩個工具,點選安裝即可。

安裝了以上的軟體包後,我們可以正常使用MySQL完成資料管理工作,但是很多時候我們需要通過編寫程式訪問MySQL。此時,在程式中需要載入MySQL驅動標頭檔案,但是預設這些驅動包是沒有安裝的,因此我們需要在Synaptic Packet Management中找到"libmysqld-dev"包並安裝。

用C語言連線MySQL資料庫有兩個步驟

1)初始化一個連線控制代碼結構

2)建立連線

所用到的函式如下:

#include <mysql.h>
MYSQL *mysql_init(MYSQL *); // 初始化連線控制代碼
MYSQL *mysql_real_connect(MYSQL *connection, 
                          const char *server_host,                        
                          const char *sql_user_name,
                          const char *sql_password, 
                          const char *db_name, 
                          unsigned int port_number, 
                          const char *unix_socket_name, 
                          unsigned int flags); //建立連線
void mysql_close(MYSQL *connection); //關閉連線
int mysql_options(MYSQL *connection, enum option_to_set, const char *argument); //設定連線選項
option_to_set的值為下列三個值之一:
MySQL_OPT_CONNECT_TIMEOUT  //連線超時前的等待秒數
MySQL_OPT_COMPRESS //網路連線中使用壓縮機制
MySQL_INIT_COMMAND //每次建立連線後傳送的命令
使用上面函式實現MySQL資料庫連線的程式如下:
/*
 * gcc -I/usr/include/mysql connect1.c -L/usr/lib/mysql -lmysqlclient -o connect1
 */
#include <stdlib.h>
#include <stdio.h>

#include <mysql.h>

int main()
{
	MYSQL *conn_ptr;  // 定義連線控制代碼

	conn_ptr = mysql_init(NULL); // 初始化連線控制代碼
	if(!conn_ptr)
	{
		fprintf(stderr, "mysql_init falied\n");
		return EXIT_FAILURE;
	}

	// 建立連線
	conn_ptr = mysql_real_connect(conn_ptr, "localhost", "root", "pwd", "test", 0, NULL, 0);
	if(conn_ptr)
	{
		printf("Connection success\n");
	}
	else
	{
		printf("Connection failed\n");
	}

	// 關閉連線
	mysql_close(conn_ptr);

	return EXIT_SUCCESS;
}
程式編譯執行後顯示“Connection success"表明程式已經成功與MySQL資料庫建立連線,並在程式結束前關閉連線。

上面的程式是在假設沒有錯誤的情況下執行,如果資料庫連線過程中出現了錯誤,我們就需要以下兩個函式來處理錯誤資訊:
unsigned int mysql_errno(MYSQL *connection); //返回錯誤程式碼(非零值)
char *mysql_error(MYSQL *connection); //返回錯誤資訊
具體使用方法如下:
/*
 * gcc -I/usr/include/mysql connect2.c -L/usr/lib/mysql -lmysqlclient -o connect2
 */
#include <stdlib.h>
#include <stdio.h>
#include <mysql.h>

int main(int argc, char *argv[])
{
	MYSQL connection;
	mysql_init(&connection); //初始化連線
	if(mysql_real_connect(&connection, "localhost", "root", "unknown", "test", 0, NULL, 0)) //建立連線
	{
		printf("Connection success\n");
		mysql_close(&connection);
	}
	else //連線失敗列印錯誤資訊
	{
		fprintf(stderr, "Connection failed\n");
		if(mysql_errno(&connection))
		{
			fprintf(stderr, "Connection error %d: %s\n", mysql_errno(&connection), mysql_error(&connection));
		}
	}

	return EXIT_SUCCESS;
}
執行上述程式,如果MySQL的登陸密碼不是unknown則列印錯誤資訊(拒絕訪問——Access denied)。

程式訪問資料庫不只是與資料庫建立連線,更重要的是通過SQL語句的執行查詢或改變資料庫中資料。執行SQL語句可以通過下列函式實現。
//執行SQL語句,成功返回0
int mysql_query(MYSQL *connection, const char *query);

SQL語句分為兩類,返回資料的SQL(SELECT)和不返回資料的SQL(UPDATE、DELETE、INSERT)。

1)不返回資料的SQL
// 返回查詢受影響的行
my_ulong mysql_affected_rows(MYSQL *connection);

對一段SQL語句執行後可以通過呼叫此函式檢視SQL語句執行後,資料庫中資料狀態改變的行數,以此判斷SQL的執行成功與否。

/*
 * gcc -I/usr/include/mysql insert1.c -L/usr/lib/mysql -lmysqlclient -o insert1
 */
#include <stdlib.h>
#include <stdio.h>
#include <mysql.h>

int main(int argc, char *argv[])
{
	int res;
	MYSQL connection;

	mysql_init(&connection);
	if(mysql_real_connect(&connection, "localhost", "root", "pwd", "test", 0, NULL, 0))
	{
		printf("Connection success\n");

		res = mysql_query(&connection, "INSERT INTO children(fname, age) VALUES('ann', 3)");

		if(!res)
		{
			printf("Inserted %lu rows\n", (unsigned long)mysql_affected_rows(&connection)); //列印受影響的行數
		}
		else
		{
			fprintf(stderr, "Insert error %d: %s\n", mysql_errno(&connection), mysql_error(&connection));
		}

		mysql_close(&connection);
	}
	else
	{
		fprintf(stderr, "Connection failed\n");
		if(mysql_errno(&connection))
		{
			fprintf(stderr, "Connection error %d: %s\n", mysql_errno(&connection), mysql_error(&connection));
		}
	}

	return EXIT_SUCCESS;
}

2返回資料的SQL

返回資料的SQL是指通過查詢語句從資料庫中取出滿足條件的資料記錄。
//一次提取所有資料
MYSQL_RES *mysql_store_result(MYSQL *connection);
//一次提取一行資料
MYSQL_RES *mysql_use_result(MYSQL *connection);
//清除結果集物件
void mysql_free_result(MYSQL_RES *result);
使用方法如下所示:
#include <stdlib.h>
#include <stdio.h>
#include <mysql.h>

MYSQL connection;
MYSQL_RES *sqlres;
MYSQL_ROW sqlrow;

int main(int argc, char *argv[])
{
	int res;

	mysql_init(&connection);

	if(mysql_real_connect(&connection, "localhost", "root", "pwd", "mysql", 0, NULL, 0))
	{
		printf("Connection success\n");
		res = mysql_query(&connection, "SELECT user, password, host from user");
		if(res)
		{
			printf("SELECT error: %s\n", mysql_error(&connection));
		}
		else
		{
			// 一次取全部資料
			sqlres = mysql_store_result(&connection);
			if(sqlres)
			{
				printf("Retrieved %lu rows\n", (unsigned long)mysql_num_rows(sqlres));
				while((sqlrow = mysql_fetch_row(sqlres)))
				{
					printf("Fetched data...\n");
				}
				if(mysql_errno(&connection))
				{
					fprintf(stderr, "Retrive error: %s\n", mysql_error(&connection));
				}

				mysql_free_result(sqlres);
			}

			// 一次取一行資料
			/*sqlres = mysql_use_result(&connection);
			if(sqlres)
			{
				while((sqlrow = mysql_fetch_row(sqlres)))
				{
					printf("Fetched data...\n");
				}
				if(mysql_errno(&connection))
				{
					printf("Retrive error: %s\n", mysql_error(&connection));
				}
				mysql_free_result(sqlres);
			}*/
		}
		mysql_close(&connection);
	}
	else
	{
		fprintf(stderr, "Connection failed\n");
		if(mysql_errno(&connection))
		{
			fprintf(stderr, "Connection error %d: %s\n", mysql_errno(&connection), mysql_error(&connection));
		}
	}

	return EXIT_SUCCESS;
}
一次取全部資料增加了網路負載,但是可以保證資料的完整性。一次取一行資料平衡了網路負載,減小了資料開銷,但是增加了時延,因為每次取資料都必須通過網路。

最後一個比較重要的功能是對資料集中的資料進行處理,可能通過列號或者列名來讀取資料。

//返回結果集中的欄位數目
unsigned int mysql_field_count(MYSQL *connection);

MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result);
void display_row()
{
	unsigned int field_count;
	field_count = 0;
	while(field_count < mysql_field_count(&connection))
	{
		printf("%s ", sqlrow[field_count]);
		field_count++;
	}
	printf("\n");
}

小結:通過以上分析,可以瞭解在Linux作業系統環境下如何通過程式建立與MySQL資料的連線,並且通過庫函式的呼叫可以實現對資料庫的增刪改查操作,在出現錯誤時,通過函式呼叫可以返回錯誤程式碼,也可以直接返回錯誤資訊。