【原創】modb功能設計之“支援部分MySQL客戶端協議”-3

摩雲飛發表於2016-05-11
 在研究完 MySQL 官方文件上對 Connector/C 的說明後,終於可以 開工實踐了,先搞個小 demo 出來執行看看。 

開發環境:Windows XP SP3 v11 + VS2010 + MySQL Connector/C 6.1.2 
測試程式碼:
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
#include <stdio.h>
#include "mysql.h"
 
int main()
{
    MYSQL mysql;
    MYSQL_RES *res = NULL;
    MYSQL_ROW row;
 
    mysql_init( &mysql );
 
    if ( NULL == ( mysql_real_connect( &mysql,"172.16.81.111","root","root", "", 0, NULL, 0 ) ) )
    {
        fprintf( stderr, "%s: %s
"
, "MoDb", mysql_error( &mysql ) );
        exit(1);
    }
 
    if ( mysql_query( &mysql, "show tables" ) ) {
        fprintf( stderr, "Error: %s
"
, mysql_error( &mysql ) );
        exit(1);
    }
    res = mysql_use_result( &mysql );
 
    printf("MySQL Tables in mysql database:
"
);
    while ( (row = mysql_fetch_row(res)) != NULL )
    {
        fprintf( stderr, "%s
"
, row[0] );
    }
 
    mysql_free_result(res);
    mysql_close( &mysql );
 
    getchar();
    return 0;
}

      工程配置好後,執行出現“無法定位程式輸入點 InitializeConditionVariable 於動態連結庫 KERNEL32.dll 上。”的錯誤。哈哈,知道為啥不(其實上一篇文章已經說明了這個問題)?我一下就想到了,但還是在度娘那邊問查了一下,給出的答案五花八門,相關的不多。其實就是因為 XP 上的 KERNEL32.dll 不支援 InitializeConditionVariable 的緣故。


解決辦法 

  • 換作業系統;
  • 降低 MySQL Connector/C 的使用版本。

       其實兩種方式都讓人覺得不爽,不過好在只是為了在 Windows 平臺上能夠對編寫的 demo 進行迅速除錯,所以使用低版本 MySQL Connector/C 獲選。 降低版本後,立刻能夠正常與 MySQL 進行協議互動了。 
      雖然你可能自以為理解了 MySQL 協議,但是還是不一定能寫出正確的協議互動,所以,最簡單的辦法就是參考一些知名的 MySQL 客戶端產品,如 Navicat for MySQL,看看別人是怎麼做互動的。

(…抓包分析過程讀者自己實踐…) 

簡單改寫後,新的測試程式碼如下:

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
#include <stdio.h>
#include "mysql.h"
 
int main()
{
    MYSQL mysql;
    MYSQL_RES *res = NULL;
    MYSQL_ROW row;
 
    mysql_init( &mysql );
 
    if ( NULL == ( mysql_real_connect( &mysql,"172.16.81.111","root","root", "", 0, NULL, 0 ) ) )
    {
        fprintf( stderr, "%s: %s
"
, "MoDb", mysql_error( &mysql ) );
        exit(1);
    }
 
    if (  mysql_query( &mysql, "SET NAMES utf8" ) )
    {
        fprintf( stderr, "Error [SET NAMES utf8]: %s
"
, mysql_error( &mysql ) );
        exit(1);
    }
 
    if ( mysql_query( &mysql, "show databases" ) ) {
        fprintf( stderr, "Error: %s
"
, mysql_error( &mysql ) );
        exit(1);
    }
    res = mysql_use_result( &mysql );
 
    printf("MySQL Tables in mysql database:
"
);
    while ( (row = mysql_fetch_row(res)) != NULL )
    {
        fprintf( stderr, "%s
"
, row[0] );
    }
 
    mysql_free_result(res);
    mysql_close( &mysql );
 
    getchar();
    return 0;
}

上述程式碼完成了連線、查詢、斷開連線的基本操作。 

在上述 demo 成功執行後,又提出瞭如下問題: 

  • 作為一個主要用於執行 sql 語句的客戶端程式,應該採用長連線實現,還是短連線實現?哪種更好?
  • 執行一條 sql 語句在客戶端實現中要呼叫到哪些 API 函式?設定哪些 option ?
  • 應該使用 mysql_use_result 獲取結果還是使用 mysql_store_result 獲取結果?


相關文章