я спрашивал Другой вопрос для моей проблемы с настройкой сортировки, которая, кажется, игнорируется / переопределяется некоторыми нежелательными значениями по умолчанию. Чтобы обойти это, я хочу использовать COLLATE
в запросах возврата «незаконное сочетание сопоставлений«ошибка. Однако, когда я пытаюсь это сделать, я получаю сообщение об ошибке» COLLATION is not valid «.
Соответствующий запрос (с другими запросами я еще не сталкивался с этой проблемой), на этот раз с COLLATE
по параметру (?
переводится в строку чисел, разделенных запятыми):
SELECT k.url
FROM kml k
WHERE (
SELECT GROUP_CONCAT(
kat.kategorie ORDER BY kat.kategorie
)
FROM kml_kategorie kat
WHERE kat.kml = k.id
) = ? COLLATE utf8_czech_ci
LIMIT 1;
При запуске я получаю следующую ошибку:
COLLATION 'utf8_czech_ci' is not valid for CHARACTER SET 'binary'
Когда я бегу show variables like "%character_set_%"
в Adminer я получаю следующие результаты:
---------------------------------------
| Variable_name | Value |
---------------------------------------
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
---------------------------------------
Когда я вызываю команду из php / mysqli, единственное отличие состоит в том, что даже character_set_filesystem
имеет значение utf8
,
Что ж, возможно, в этом случае настройки базы данных используются независимо от того, что показано в mysqli. Но затем я попытался решить любые проблемы принуждения, добавив COLLATE
в агрегатную функцию, GROUP_CONCAT
:
SELECT k.url
FROM kml k
WHERE (
SELECT GROUP_CONCAT(
kat.kategorie ORDER BY kat.kategorie COLLATE utf8_czech_ci
)
FROM kml_kategorie kat
WHERE kat.kml = k.id
) = ?
LIMIT 1;
Теперь ошибка следующая:
COLLATION 'utf8_czech_ci' is not valid for CHARACTER SET 'latin1'
Вы можете видеть, что нет latin1
среди значений переменных charset. Раньше было значение character_set_server
прежде чем я изменил my.cnf
файл. Соответствующая часть теперь выглядит так:
## UTF 8 Settings
#init-connect=\'SET NAMES utf8\'
collation_server=utf8_czech_ci
character_set_server=utf8
character-set-filesystem=utf8
#skip-character-set-client-handshake
#character_sets-dir="C:/xampp/mysql/share/charsets"
Откуда берутся кодировки, показанные в сообщениях об ошибках (и вызывающих проблему)? Меня немного смущают различия между запросом переменных у mysqli / php и adminer, и полностью сбит с толку некоторыми другими переменными, делающими этот еще больший беспорядок. Как его очистить и изменить переменные так, чтобы хотя бы этот обходной путь COLLATE работал?
Это в основном подвопрос мой связанный вопрос, но достаточно разные, чтобы заслужить расщепление; объединенные два вопроса были бы такими же беспорядочными, как и переменные моей базы данных. Тем не менее, вполне вероятно, что решение одного из них приведет к решению другого; после ответа вы можете рассмотреть вопрос об ответе на другой вопрос в виде краткого изложения вашего первого ответа + примечания о том, как оно относится к проблеме, указанной в вопросе.
РЕДАКТИРОВАТЬ: я нашел обходной путь для этого одного конкретного случая. Тем не менее, я до сих пор не нашел почему запросы, сделанные через Adminer и Mysqli, дали разные результаты а также особенно почему сообщение об ошибке указывает на кодировки, не включенные ни в одну переменную?
Что такое тип данных kat.kategorie?
GROUP_CONCAT( kat.kategorie
ORDER BY CONVERT(kat.kategorie USING utf8) COLLATE utf8_czech_ci
)
Вам также может понадобиться звонок CAST(... AS CHAR)
,
В будущем не смешивайте наборы символов.
GROUP_CONCAT
и пара других функций, которые включают в себя объединение вещей, имеют проблему при определении того, каким должен быть тип результата. В некоторых случаях это вызывает и вызывает результат BINARY
, что еще хуже, чем вы столкнулись.
Я считаю, что где-то есть латынь, которая привела к вашей конкретной проблеме. Копай в админке. Давайте посмотрим, ШОУ CREATE TABLE кат.
Я сделал другой обходной путь: я создал представление в своей базе данных, чтобы избежать вызова GROUP_CONCAT
в параметризованном запросе mysqli. Ошибка больше не появляется, но Я до сих пор не считаю это полностью решенным, потому что есть некоторые странные вещи, которые я не понимаю (переменные установлены неправильно и т. д.), и я не хочу, чтобы они создавали больше проблем.
Вид:
CREATE
ALGORITHM=UNDEFINED DEFINER=`root`@`localhost`
SQL
SECURITY DEFINER
VIEW `kml_kat_vw` AS SELECT
`kml_kategorie`.`kml` AS `_kml`,
group_concat(
`kml_kategorie`.`kategorie`
ORDER BY `kml_kategorie`.`kategorie` ASC separator ','
) AS `_kategorie`
FROM `kml_kategorie`
GROUP BY `kml_kategorie`.`kml`
Новый запрос:
SELECT k.url
FROM kml k
JOIN kml_kat_vw kat ON kat._kml = k.id
WHERE kat._kategorie = ?;