2013-07-28 39 views
2

與UTF8科協工作我們有一個查詢是這樣的:ADODB功能不會MySQL查詢

select C.* from stream_data AS sd 
JOIN Conversations AS C 
ON (C.conversationReferenceId = sd.stream_data_id AND smAccountId = ?) 
WHERE sd.stream_id = ? LIMIT 1 

,我們運行使用ADODB。像這樣:

$object = new Conversation(); 
$object->LoadFromRawQuery("select C.* from stream_data AS sd JOIN Conversations AS C ON (C.conversationReferenceId = sd.stream_data_id AND smAccountId = ?) WHERE sd.stream_id = ? LIMIT 1", array($socialmediaAccountId, $parentSourceId)); 

(注:我們有ADODB的定製版本,有一個在AdoDB_RecordSet類稱爲LoadFromRawQuery方法,但可以使用標準的execute()方法調用中可以看出這個問題,所以我讓它。是)

爲了改善這種查詢的性能(根據我們的指標),我們增加了一個轉換操作符:

#Query: 
select C.* from stream_data AS sd 
JOIN Conversations AS C 
ON (C.conversationReferenceId = cast(sd.stream_data_id as char) collate utf8_unicode_ci AND smAccountId = ?) 
WHERE sd.stream_id = ? LIMIT 1 

#PHP 
$object = new Conversation(); 
$object->LoadFromRawQuery("select C.* from stream_data AS sd JOIN Conversations AS C ON (C.conversationReferenceId = cast(sd.stream_data_id as char) collate utf8_unicode_ci AND smAccountId = ?) WHERE sd.stream_id = ? LIMIT 1", array($socialmediaAccountId, $parentSourceId)); 

這兩種操作在控制檯工作,但在ADODB,第一個操作成功,而第二次操作失敗。我們所有的桌子都使用UTF8字符集。

幫助。

回答

1

問題在於 - 默認情況下,ADODB不知道數據庫的字符集。因此,它要求的MySQL通過查詢來提供相同的,如:

mysql> SELECT default_character_set_name FROM information_schema.SCHEMATA S 
    -> WHERE schema_name = "xxxxxx"; 
+----------------------------+ 
| default_character_set_name | 
+----------------------------+ 
| latin1      | 
+----------------------------+ 
1 row in set (0.00 sec) 

這將返回latin1的,因爲在MySQL默認字符集的Latin1的是latin1的。您可以通過添加字符集(http://dev.mysql.com/doc/refman/5.0/en/create-database.html)在創建數據庫時修復它。由於MySQL的數據庫位於latin1上,但表格位於utf8中,因此MySQL會努力返回latin1。現在,AdoDB將連接設置爲latin1。

當此與您覈對混合 「utf8_unicode_ci」 中,MySQL會返回一個錯誤:

ErrorMsg: COLLATION 'utf8_unicode_ci' is not valid for CHARACTER SET 'latin1' 

現在,你有兩個選擇。在建立數據庫連接,請撥打以下強行連接設置爲UT8字符集:

$object->DB()->SetCharSet('utf8'); 
// Or 
$connection->SetCharSet('utf8'); 

建議:

另一方面,不是鑄造的元素爲字符串,你正好連接'',然後在這一點上,MySQL會爲你輸入它,並且使用正確的排序規則進行處理,因此你將不會出現錯誤 - 並且我使用EXPLAIN進行了檢查 - 同時使用相同的索引和排序結構:

#Query: 
select C.* from stream_data AS sd 
JOIN Conversations AS C 
ON (C.conversationReferenceId = CONCAT('', sd.stream_data_id) AND smAccountId = ?) 
WHERE sd.stream_id = ? LIMIT 1 

#PHP 
$object = new Conversation(); 
$object->LoadFromRawQuery("select C.* from stream_data AS sd JOIN Conversations AS C ON (C.conversationReferenceId = CONCAT('', sd.stream_data_id) AND smAccountId = ?) WHERE sd.stream_id = ? LIMIT 1", array($socialmediaAccountId, $parentSourceId)); 

echo("\r\n"."SQL : ".'select C.* from stream_data AS sd JOIN Conversations AS C ON (C.conversationReferenceId = CONCAT(\'\', sd.stream_data_id) AND smAccountId = ?) WHERE sd.stream_id = ? LIMIT 1'."\r\n"); 
echo("\r\n".'RESULT OBJECT AFTER DOING THE CONCAT : '."\r\n".json_encode($parentConversation)."\r\n");