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_RecordSet クラスに LoadFromRawQuery というメソッドを持つ AdoDB のカスタム バージョンがありますが、標準の 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 では、最初の操作は成功し、2 番目の操作は失敗します。すべてのテーブルは UTF8 文字セットです。

ヘルプ。

4

1 に答える 1

1

問題は、デフォルトでは ADODB が DB の文字セットを認識していないことです。そのため、次のようなクエリを介して同じものを提供するように 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 を返します。MySQL の DB は latin1 にあるが、テーブルは utf8 にあるため、文字セット ( http://dev.mysql.com/doc/refman/5.0/en/create-database.html )を追加することで、データベースの作成時に修正できます。 、MySQL は熱心に latin1 を返します。ここで、AdoDB は接続を latin1 に設定します。

これが照合順序「utf8_unicode_ci」と混在すると、MySQL はエラーを返します。

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

ここで、2 つのオプションがあります。DB 接続をセットアップするときは、以下を呼び出して接続を強制的に ut8 charset に設定します。

$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");
于 2013-07-28T02:18:28.367 に答える