mysql -比较包含国家字符的字符串常量的问题

rqdpfwrv  于 2023-03-11  发布在  Mysql
关注(0)|答案(1)|浏览(140)

我在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 'Ł%'也不返回任何行。无论如何,我希望有更干净和简单的解决方案。
有没有可能在模式或会话级别覆盖问题行为?至少-有没有不太复杂且不过时的代码可以在这里使用?

laximzn5

laximzn51#

如果使用空字符串常量,则它与表没有关联,因此它不使用该表的排序规则,而是使用会话的排序规则。

mysql> SELECT 'Lucjan' LIKE 'Ł%' as same;
+------+
| same |
+------+
|    1 |
+------+

我可以显式地告诉任何一个字符串参数使用哪种排序规则,这将覆盖会话排序规则。

mysql> SELECT 'Lucjan' LIKE 'Ł%' collate utf8mb4_pl_0900_ai_ci as same;
+------+
| same |
+------+
|    0 |
+------+

如果显式地为任一字符串参数指定了排序规则,则此方法有效。

mysql> SELECT 'Lucjan' collate utf8mb4_pl_0900_ai_ci LIKE 'Ł%' as same;
+------+
| same |
+------+
|    0 |
+------+

或者,我可以更改会话排序规则,然后后续的字符串常量表达式使用该排序规则。

mysql> set names utf8mb4 collate utf8mb4_pl_0900_ai_ci;

mysql> SELECT 'Lucjan' LIKE 'Ł%' as same;
+------+
| same |
+------+
|    0 |
+------+

相关问题