2013-07-28 2 views
2

У нас есть запрос, как это:функция ADOdb не работает с utf8 броском в MySQL Query

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, который имеет метод, называемый LoadFromRawQuery в классе AdoDB_RecordSet, но проблему можно увидеть, используя стандартный 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. Вы можете исправить его при создании времени базы данных, добавив charset (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"); 
Смежные вопросы