連接/斷開MySQL數據庫服務器
好,我們接著上一篇繼續編寫第一個 MySQL 數據庫應用程序。接下來,我們要寫代碼連接到 MySQL 的數據庫服務器。需要說明一下,我們通過一本書,叫《MySQL, 4th Edition》,來學習 MySQL 數據庫編程,所以樣例代碼都摘錄自這本書。并且為了方便編譯和測試書里的代碼,我們都是按照書里前邊 MySQL 數據庫的操作,預先創建了用戶和樣例數據庫:
用戶名:sampadm
密碼:secret
數據庫名稱:sampdb
有了這些前提條件,我們就可以開始學習書中的代碼了。以下就是測試數據庫服務器的連接和斷開代碼:
// exec_stmt.cpp : 定義控制臺應用程序的入口點。//#include "stdafx.h"#include <my_global.h> // 這個頭文件必須是第一個被包含的文件 #include <my_sys.h>#include <mysql.h>#include <my_getopt.h>#include <m_string.h> // 需要的函數strdup()在這個頭文件中聲明static char *opt_host_name = NULL; // 服務器主機 (默認=localhost)static char *opt_user_name = "sampadm"; // 用戶名 (默認=登陸名)static char *opt_passWord = "secret"; // 密碼 (默認=無)static unsigned int opt_port_num = 0; // 端口號(使用內置值)static char *opt_socket_name = NULL; // 套接字名稱 (使用內置值)static char *opt_db_name = "sampdb"; // 數據庫名稱(默認=無)static unsigned int opt_flags = 0; // 連接標志connection flags (無)static int ask_password = 0; // 是否請求密碼static MYSQL *conn; // 連接數據庫句柄的指針int _tmain(int argc, _TCHAR* argv[]){ // 將一個全局變量指向程序的名稱并調用my_init()。 // 這個全局變量會被MySQL庫用于錯誤信息中。// MY_INIT (argv[0]); // 執行一些設置操作 my_init(); // 初始化客戶端庫 if (mysql_library_init(0, NULL, NULL)) { fPRintf(stderr, "mysql_library_init() falied/n"); exit(1); } // 初始化連接句柄 conn = mysql_init(NULL); if (conn == NULL) { fprintf(stderr, "mysql_init() failed (probably out of memory)/n"); exit(1); } // 連接到服務器 if (mysql_real_connect(conn, opt_host_name, opt_user_name, opt_password, opt_db_name, opt_port_num, opt_socket_name, opt_flags) == NULL) { fprintf(stderr, "mysql_real_connect() failed/n"); mysql_close(conn); exit(1); } // ... 在這里發出查詢語句并處理返回的結果 ... // 斷開與服務器的連接 mysql_close(conn); // 停止客戶端庫 mysql_library_end(); return 0;}以上代碼中的注釋已經基本把程序的流程說清楚了。這里邊還有幾點需要說明一下。
1. 我們把用戶名、密碼和數據庫名稱寫在程序代碼開頭的全局變量聲明中。這種硬編碼顯然是不對的。未來要修改代碼,讓用戶自己從外部給程序提供這些信息。因為目前僅是測試服務器的連接與斷開,所以先這樣。
2. 這本書里用到的代碼都是在linux上用GCC編譯器編譯的。雖然作者說 Windows 用戶一樣能編譯,但是貌似并不完全如此。畢竟大家的開發環境千差萬別。比如,請注意在 _tmain() 函數的開頭,書上原來的代碼說要調用一個叫做 MY_INIT 的宏,并且把程序的名稱作為參數傳給這個宏。說是這個宏會做一些初始化操作,并且紀錄程序的名稱,未來可以用這個名稱給用戶顯示一些錯誤信息(如果有錯誤發生的話)。但是VS.NET 2003無法編譯這個函數,總是報錯。于是我們在 my_sys.h 這個文件中,在第40行,找到了關于這個宏的定義:

我們發現這個宏實際是將傳遞給參數 name 的值保存在一個叫 my_progname 的全局變量中,然后調用函數 my_init()。幸運的是,如果我們不調用這個宏,而是直接調用 my_init() 這個函數,編譯可以通過。于是我們就修改了代碼,直接調用 my_init() 。未來還有一個函數調用無法通過編譯,這個函數是 get_tty_password() 。這個函數是用來在命令行提示符下向用戶索要密碼的。但是這個函數并不在我們的 VS 編譯器自帶的函數庫里,所以編譯器會提醒找不到這個函數。在網上能找到這段函數的定義,比如在這里。但是好像會把問題搞復雜,增加編譯咱們第一個 MySQL 程序的難度。所以我們選擇不調用這個函數。只能留在以后,對 C/C++ 越來越熟悉后,再回來研究這個函數吧。
現在,如果你在 VS 里選擇菜單“生成-〉生成 exec_stmt”,程序就會編譯通過(至少在我們的機器上是這樣的)。

好,我們來運行這個程序試驗一下。在 Windows xp 上依次選擇“開始-〉所有程序-〉附件-〉命令提示符”,然后定位到編譯的可執行程序所在的目錄,運行程序:

如果運氣好的話,不會有錯誤報告,什么事情也不會發生,因為我們的代碼除了連接/斷開數據庫服務器外,啥也沒干。
先到這里。
順便說一下,在這里只是摘錄了書中必要的代碼。要想完整、系統地學習 MySQL 編程,還是要自己買書,重頭到尾好好學習。
新聞熱點
疑難解答