COLLATION is not valid for CHARACTER SET 不符合我的设置

COLLATION is not valid for CHARACTER SET not corresponding to my settings

我问了 another question for my problem with collation setting, which seems to be ignored/overriden by some unwanted defaults. To workaround this, I want to use COLLATE in the queries returning "illegal mix of collations" 错误。但是,当我尝试这样做时,我得到了 "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'

当我在 Adminer 中 运行 show variables like "%character_set_%" 时,我得到以下结果:

---------------------------------------  
| 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'

可以看到charset变量值中没有latin1。在我修改my.cnf文件之前,它曾经是character_set_server的值。它的相关部分现在看起来像这样:

## 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 解决方法有效?

这基本上是 my linked question 的一个子问题,但不同之处足以值得拆分;这两个问题加在一起会像我的数据库变量一样混乱。但是,很可能其中一个的解决方案也会使另一个也得到解决;回答后,您可以考虑通过总结您的第一个答案+说明它如何适用于问题中指定的问题来回答另一个问题。

编辑:我找到了 这个特殊案例。但是,我仍然没有找到为什么通过 Adminer 和 Mysqli 进行的查询返回不同的结果尤其是为什么错误消息指向不包含在任何变量中的字符集?

我做了另一个解决方法:我在我的数据库中创建了一个视图以避免在 mysqli 参数化查询中调用 GROUP_CONCAT。错误不再出现,但我仍然认为它没有完全解决,因为有些奇怪的事情我不明白(变量设置不正确等)而且我不不想让他们再出问题。

观点:

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 = ?;

kat.kategorie 的数据类型是什么?

GROUP_CONCAT( kat.kategorie
              ORDER BY CONVERT(kat.kategorie USING utf8) COLLATE utf8_czech_ci 
            )

您可能还需要致电 CAST(... AS CHAR)

以后不要混用CHARACTER SET。

GROUP_CONCAT,以及其他一些涉及组合事物的函数,在推断结果类型应该是什么方面存在问题。在某些情况下,它 punts 并调用结果 BINARY,这比你遇到的还要糟糕。

我相信某个地方有一个 latin1 导致了您的特定问题。深入了解管理员。让我们看看 SHOW CREATE TABLE kat.