我在MySQL 8.0.32中有以下测试方案:
CREATE SCHEMA `test_schema` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_pl_0900_ai_ci ;
CREATE TABLE `test_schema`.`test_table` (
`test_column` VARCHAR(64) NULL);
INSERT INTO `test_schema`.`test_table` (`test_column`) VALUES('Łucja');
INSERT INTO `test_schema`.`test_table` (`test_column`) VALUES('Lucjan');
正如人们所料,没有为表和列提供显式排序规则,因此它们继承了模式设置(我已经检查过了,为了清楚起见,跳过了SQL语句)。
现在我运行以下代码并得到预期的结果:
mysql> SELECT * FROM test_table WHERE test_column LIKE 'Ł%';
+-------------+
| test_column |
+-------------+
| Łucja |
+-------------+
在波兰语字母是完全不同的东西从字母L和校对处理正确。
我本以为下面的查询不会返回任何结果,但我在这里感到惊讶:
mysql> SELECT * FROM test_table WHERE 'Lucjan' LIKE 'Ł%';
+-------------+
| test_column |
+-------------+
| Łucja |
| Lucjan |
+-------------+
经过几次类似的测试后,我知道“独立”字符串(即不是来自表)在比较时不使用模式排序规则设置,例如SELECT 1 WHERE 'L' LIKE 'Ł%'
返回一行。
我知道这种行为可以通过使用BINARY
关键字来覆盖-SELECT 1 WHERE 'L' LIKE BINARY 'Ł%'
返回空结果集。无论如何,当我尝试在存储函数中使用它时,我得到了警告:
1287 'BINARY expr' is deprecated and will be removed in a future release. Please use CAST instead
事实上,SELECT 1 WHERE CAST('L' AS CHAR(6) CHARSET latin2) LIKE 'Ł%'
也不返回任何行。无论如何,我希望有更干净和简单的解决方案。
有没有可能在模式或会话级别覆盖问题行为?至少-有没有不太复杂且不过时的代码可以在这里使用?
1条答案
按热度按时间laximzn51#
如果使用空字符串常量,则它与表没有关联,因此它不使用该表的排序规则,而是使用会话的排序规则。
我可以显式地告诉任何一个字符串参数使用哪种排序规则,这将覆盖会话排序规则。
如果显式地为任一字符串参数指定了排序规则,则此方法有效。
或者,我可以更改会话排序规则,然后后续的字符串常量表达式使用该排序规则。