2013-11-05 28 views
0

我嘗試做以下內容的請求mysql_query:C++變量Gettext中的得到可變

  1. 獲得用戶名鍵入到userField
  2. 使用戶名爲一個搜索請求mysql_query作爲變量

我有一個很難讓過去的第2階段以來的mysql_query需要一個const char *作爲查詢字符串,而我只能得到用戶名爲char *或wchar_t的*

我也用unicode編譯。

我現在代碼:

void mysql_connect(HWND hLoginWnd) { 

MYSQL *con, mysql; 
MYSQL_RES *res; 
mysql_init(&mysql); 

mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "utf8"); 

mysql_real_connect(&mysql, "localhost", "root", "", "treenitaulu", 3306, NULL, 0); 

char name[512], pass[512]; 
int lenUser = SendMessage(userField, WM_GETTEXT, 512, (LPARAM)name); 
int lenPass = SendMessage(passField, WM_GETTEXT, 512, (LPARAM)pass); 

if(lenUser > 0 && lenPass > 0) { 

    std::string query = "SELECT pass FROM users WHERE name='" + std::string(name) + "'"; 

    mysql_query(&mysql, query.c_str()); 

} 

} 

我該怎麼辦?

回答

1

您正在將SQL字符集設置爲UTF-8,因此請使用WideCharToMultiByte()將retreived UI Unicode字符串轉換爲UTF-8,然後將轉換後的數據傳遞給數據庫查詢。可以使用char緩衝區存儲UTF-8編碼的數據,並且您可以傳遞char*(或char[]),其中const char*是預期的。例如:

std::string Utf8Encode(WCHAR *wStr, int wLen) 
{ 
    int utf8len = WideCharToMultiByte(CP_UTF8, 0, wStr, wLen, NULL, 0, NULL, NULL); 
    if (utf8len > 0) 
    { 
     std::vector<char> utf8(utf8len); 
     utf8len = WideCharToMultiByte(CP_UTF8, 0, wStr, wLen, &utf8[0], utf8len, NULL, NULL); 
     if (utf8len > 0) 
      return std::string(&utf8[0], utf8len); 
    } 
    return std::string(); 
} 

void mysql_connect(HWND hLoginWnd) 
{ 
    MYSQL *con, mysql; 
    MYSQL_RES *res; 
    mysql_init(&mysql); 

    mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "utf8"); 

    mysql_real_connect(&mysql, "localhost", "root", "", "treenitaulu", 3306, NULL, 0); 

    WCHAR name[512]; 
    int lenUser = SendMessage(userField, WM_GETTEXTW, 512, (LPARAM)name); 

    if (lenUser > 0) 
    { 
     std::string query = "SELECT pass FROM users WHERE name='" + Utf8Encode(name, lenUser) + "'"; 
     mysql_query(&mysql, query.c_str()); 
     ... 
    } 
} 

這樣說,你真的需要在動態構建SQL語句時轉義字符串。它是安全的,因爲它不容易出現SQL注入攻擊:

std::string Utf8EncodeAndEscape(MYSQL *mysql, WCHAR *wStr, int wLen) 
{ 
    int utf8len = WideCharToMultiByte(CP_UTF8, 0, wStr, wLen, NULL, 0, NULL, NULL); 
    if (utf8len > 0) 
    { 
     std::vector<char> utf8(utf8len); 
     utf8len = WideCharToMultiByte(CP_UTF8, 0, wStr, wLen, &utf8[0], utf8len, NULL, NULL); 
     if (utf8len > 0) 
     { 
      std::vector<char> escaped(utf8len*2+1); 
      unsigned long escapedLen = mysql_real_escape_string(mysql, &escaped[0], &utf8[0], utf8len); 
      if (escapedLen > 0) 
       return std::string(&escaped[0], escapedLen); 
     } 
    } 

    return std::string(); 
} 

void mysql_connect(HWND hLoginWnd) 
{ 
    MYSQL *con, mysql; 
    MYSQL_RES *res; 
    mysql_init(&mysql); 

    mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "utf8"); 

    mysql_real_connect(&mysql, "localhost", "root", "", "treenitaulu", 3306, NULL, 0); 

    WCHAR name[512]; 
    int lenUser = SendMessage(userField, WM_GETTEXTW, 512, (LPARAM)name); 

    if (lenUser > 0) 
    { 
     std::string query = "SELECT pass FROM users WHERE name='" + Utf8EncodeAndEscape(&mysql, name, lenUser) + "'"; 
     mysql_query(&mysql, query.c_str()); 
     ... 
    } 
} 

參數化查詢是一樣安全,但比動態SQL語句更有效,特別是如果你需要執行相同的語句多次:

std::wstring Utf8Decode(char *utf8Str, int utf8Len) 
{ 
    int wlen = MultiByteToWideChar(CP_UTF8, 0, utf8Str, utf8Len, NULL, 0); 
    if (wLen > 0) 
    { 
     std::vector<wchar_t> wStr(wLen); 
     wLen = MultiByteToWideChar(CP_UTF8, 0, utf8Str, utf8Len, &wStr[0], wLen); 
     if (wLen > 0) 
      return std::wstring(&wStr[0], wLen); 
    } 
    return std::wstring(); 
} 

MYSQL_STMT *stmt = mysql_stmt_init(&mysql); 
if (stmt) 
{  
    std::string query = "SELECT pass FROM users WHERE name=?" 
    if (mysql_stmt_prepare(stmt, query.c_str(), query.length()) == 0) 
    { 
     if (mysql_stmt_param_count(stmt) == 1) 
     { 
      std::string utf8User = Utf8Encode(name, lenUser); 
      unsigned long utf8len = utf8User.length(); 
      MYSQL_BIND param = {0}; 
      param.buffer_type = MYSQL_TYPE_STRING; 
      param.buffer = utf8User.c_str(); 
      param.buffer_length = utf8len; 
      param.length = &utf8len; 
      param.is_unsigned = true; 
      mysql_stmt_bind_param(stmt, &param); 

      char result[512]; 
      unsigned long resultLen = 0; 
      MYSQL_BIND result = {0}; 
      param.buffer_type = MYSQL_TYPE_STRING; 
      param.buffer = &result[0]; 
      param.buffer_length = 512; 
      param.length = &resultlen; 
      param.is_unsigned = true; 
      mysql_stmt_bind_result(stmt, &result); 

      if (mysql_stmt_execute(stmt) == 0) 
      { 
       mysql_stmt_fetch(stmt); 
       mysql_stmt_free_result(stmt); 

       SendMessage(passField, WM_SETTEXTW, 0, (LPARAM) Utf8Decode(result, resultLen).c_str()); 
      } 
     } 
    } 
} 

mysql_stmt_close(stmt); 
+0

聖竹。那個傻瓜做了個訣竅! Unicode使生活如此艱難......謝謝你。哦,什麼是參數化查詢?谷歌沒有帶來任何亮光。編輯:找到它。 「準備好的聲明」。 –