2

我们有一个这样的查询:

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));

这两个操作都在 Console 中工作,但在 AdoDB 中,第一个操作成功,而第二个操作失败。我们所有的表格都使用 UTF8 字符集。

帮助。

4

1 回答 1

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,因为 Latin1 中 mysql 中的默认字符集是 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 将为您转换它并使用正确的排序规则进行转换,因此您不会有错误 - 我检查使用解释 - 转换和连接版本都使用相同的索引和排序结构:

#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");
于 2013-07-28T02:18:28.367 回答