Ошибка PHP ?: MySQL (MariaDB 10.4.8) дает мне «Недопустимое сочетание параметров сортировки», но столбцы имеют тот же тип параметров сортировки - PullRequest
0 голосов
/ 24 октября 2019

(Обновление: найден обходной путь, добавлен в конец оригинального вопроса здесь - но почему обходной путь работает / необходим?)

Я только что обновил свою базу данных для поддержки UTF-8и этот SQL не выполняется при вызове из PHP:

SELECT ID FROM people WHERE Email = 'myemail@example.com' AND md5(PasswordHashed) = '26Ba48f4df2dba59b00d80c4c09a90e78'

Сообщение об ошибке: Недопустимое сочетание параметров сортировки (utf8mb4_unicode_ci, COERCIBLE) и (utf8mb4_general_ci, COERCIBLE) для операции'='

SQL работает FINE, когда я вставляю его прямо в клиент mysqld. Так что я думаю, что это связано с тем, как PHP подключается к базе данных. Код для установления соединения прост:

$this->dbc = mysqli_connect( null, 'myuser', '', 'mytable', 0, '/var/lib/mysql/mysql.sock' );
if ( $this->dbc ) {
    $this->dbc->set_charset( "utf8mb4" );
    $this->dbc->query( 'SET collation_connection = utf8mb4_unicode_ci;' );
}

И все же он не работает. (Насколько я вижу, все другие запросы SQL в коде работают нормально, так что это очень странно.)

Подтверждено, что с существующими параметрами сортировки все в порядке:

Сортировка самой базы данных - utf8mb4_unicode_ci (подтверждено с помощью SELECT @@collation_database;)

Сортировка на самой таблице - utf8mb4_unicode_ci (подтверждено с помощью show table status;)

И show full columns from people; подтверждает, что:

  • Email - это varchar (70) с сопоставлением utf8mb4_unicode_ci
  • PasswordHashed - это varchar (255) с сопоставлением utf8mb4_unicode_ci
  • ID - это int (10) без знака без сопоставления

В моей базе данных файл my.cnf содержит следующее:

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci

(Я также добавил и удалил character-set-client-handshake=FALSE из файла my.cnf,как упоминалось в некоторых других постах. Без изменений.)

Как ни странно, в сообщении об ошибке упоминается utf8mb4_ general _ci, но я не могу найти что-либо , для которого установлено это значение. сверка. Все, что я могу найти, чтобы проверить это utf8mb4_unicode_ci, и я трижды проверил это.

Я запустил mysqlcheck, чтобы восстановить таблицы, и перезапустил сервер тоже. Я выкинул всю таблицу и повторно импортировал ее (думая, что перестройка таблицы и ее индексов с нуля поможет). Ничего из этого не помогает.

Я бегу mariadb Ver 15.1 Distrib 10.4.8-MariaDB, for Linux (x86_64) using readline 5.1

Итак ... что происходит? !! Почему я получаю это сообщение об ошибке и почему он думает, что что-то utf8mb4_general_ci?


ОБНОВЛЕНИЕ: найдено решение, но почему?

Код, которыйПри возникновении ошибки используются подготовленные операторы mysqli, поэтому это выглядит так:

$sql = "SELECT ID FROM people
        WHERE Email = ? AND
        MD5(PasswordHashed) = ?";

...prepare SQL...
...bind SQL parameters...
...execute()...

Я изменил его на:

$sql = "SELECT ID FROM people
        WHERE Email = ? AND
        CAST(MD5(PasswordHashed) AS
             CHAR CHARACTER SET utf8mb4) = ?";

И теперь он работает нормально. ?? !!?

Так что я думаю, что это проблема того, как PHP-класс mysqli работает с драйвером mysql. Как я уже упоминал выше, оригинальный SQL отлично работает, когда я «готовлю» его вручную и просто вставляю в командную строку mysql ... так что я действительно не думаю, что он имеет какое-либо отношение к кодировке или сопоставлению в любой точке,Я думаю, что это какая-то странная ошибка, когда подготовленная переменная, вставляемая классом mysqli, использовала странный набор символов / сопоставление.

Но: также обратите внимание, что в исходном сообщении об ошибке содержалась жалоба на сопоставление, ноМой обходной путь исправил проблему, применяя набор символов (не сопоставление). Очень странно.

Почему мой обходной путь удался? Это где-нибудь задокументировано? Это ошибка PHP?

...