本篇为理清字符集的续篇(上一篇:第06期:梳理 MySQL 字符集的相关概念),重点讲述字符集涉及到的 sql 语句用法。

一、character introducer翻译过来就是字符引导。也就是针对字符串,显式的给定一个字符编码和排序规则,不受系统参数的影响。语法很简单:

[_charset_name] 'string' [COLLATE collation_name]

示例:

字符串"北京加油❤!"

-- 字符集 utf8mb4,排序规则 utf8mb4_binselect _utf8mb4 "北京加油❤!" collate utf8mb4_bin as result;+------------------+| result           |+------------------+| 北京加油❤!       |+------------------+1 row in set (0.00 sec)-- 字符集 utf8mb4,collate 字句缺失,此时对应排序规则为utf8mb4_w0900_ai_ciselect _utf8mb4 "北京加油❤!" as result;+------------------+| result           |+------------------+| 北京加油❤!       |+------------------+1 row in set (0.00 sec)-- 字符集缺失,此时字符集按照参数 @@character_set_connection 值来指定。mysql> select "北京加油❤!" collate gb18030_chinese_ci as result;ERROR 1253 (42000): COLLATION 'gb18030_chinese_ci' is not valid for CHARACTER SET 'utf8mb4'-- 查看变量 @@character_set_connection,确认其字符集不包含排序规则 gb18030_chinese_ci,所以以上语句报错。mysql> select @@character_set_connection;+----------------------------+| @@character_set_connection |+----------------------------+| utf8mb4                    |+----------------------------+1 row in set (0.00 sec)-- 那给下正确的排序规则 utf8mb4_bin,执行正确。mysql> select "北京加油❤!" collate utf8mb4_bin as result;+------------------+| result           |+------------------+| 北京加油❤!       |+------------------+1 row in set (0.00 sec)-- 字符集和排序规则都不指定,此时字符串对应的字符集和排序规则和参数 @@character_set_connection 一致。select "北京加油❤!" as result;-- 那这条语句其实被 MySQL 解释为select _utf8mb4 "北京加油❤!" collate utf8mb4_0900_ai_ci as result;

总结 Introducer 使用规则:

二、字符集转换函数1. convert 函数convert 函数类似于 introducer,不过只能指定字符集。举个例子,通过 convert 函数转换字符串"北京加油❤!"的编码为 utf8mb4。不过前提是转换前后字符集一定要兼容。

-- 正确的转换mysql> select convert("北京加油❤!" using utf8mb4) ;+-------------------------------------------+| convert("北京加油❤!" using utf8mb4)       |+-------------------------------------------+| 北京加油❤!                                |+-------------------------------------------+1 row in set (0.00 sec)-- 错误的转换,字符集编码不兼容。mysql> select convert("北京加油❤!" using latin1) ;+------------------------------------------+| convert("北京加油❤!" using latin1)       |+------------------------------------------+| ?????!                                   |+------------------------------------------+1 row in set (0.00 sec)

2. charset 函数

检测字符串的字符集。可以检测出当前字符串在当前 session 的字符集。

mysql> set @a="北京加油❤!";Query OK, 0 rows affected (0.00 sec)mysql> select charset(@a);+-------------+| charset(@a) |+-------------+| utf8        |+-------------+1 row in set (0.00 sec)

3. set names 语句

语法为:

SET NAMES {'charset_name'[COLLATE 'collation_name'] | DEFAULT}

这条语句最常用,可是也最容易被滥用,比如语句:

set names latin1 collate latin1_bin;

执行后会默认执行一系列语句,也就是把非服务端的相关参数给重新设定了。

set session character_set_results = latin1;set session character_set_client = latin1;set session character_set_connection=latin1;set session collation_connection = latin1_bin;

那现在重新执行确认一下,跟 introducer 一样,没有指定 collate 语句,默认为字符集对应的排序规则。

mysql> set names latin1 ;Query OK, 0 rows affected (0.00 sec)-- 那这里看到相关参数值全部被改了。mysql> select * from performance_schema.session_variables where variable_name in ('character_set_connection','collation_connection','character_set_results','character_set_client');+--------------------------+-------------------+| VARIABLE_NAME            | VARIABLE_VALUE    |+--------------------------+-------------------+| character_set_client     | latin1            || character_set_connection | latin1            || character_set_results    | latin1            || collation_connection     | latin1_swedish_ci |+----------------------------------------------+

那如果想改回默认值,简单执行:

mysql> set names default;Query OK, 0 rows affected (0.00 sec)mysql> select * from performance_schema.session_variables where variable_name in ('character_set_connection','collation_connection','character_set_results','character_set_client');+--------------------------+--------------------+| VARIABLE_NAME            | VARIABLE_VALUE     |+--------------------------+--------------------+| character_set_client     | utf8mb4            || character_set_connection | utf8mb4            || character_set_results    | utf8mb4            || collation_connection     | utf8mb4_0900_ai_ci |+--------------------------+--------------------+4 rows in set (0.00 sec)

不过有一点要注意的是,并不是所有字符集都适用于这条语句,比如定长字符集 utf32,设置就会报错。因为变量 @@character_set_client 不支持这个字符集。

mysql> set names utf32;ERROR 1231 (42000): Variable 'character_set_client' can't be set to the value of 'utf32'

4. set character set 语句语法为:

SET {CHARACTER SET | CHARSET}{'charset_name' | DEFAULT}

类似语句 set names,同样是设置以下三个 session 参数:

  • character_set_results

  • character_set_client

  • character_set_connection

同样是可以恢复默认值,还有同样的限制规则等。不过有两点不同:1)参数 character_set_connection 的值不会被设定为指定的字符集,而是继承参数 character_set_database 所设定的字符集。示例:

mysql> set character set latin1;Query OK, 0 rows affected (0.01 sec)-- 检索结果显示,参数 character_set_connection 的值和 character_set_database 的值一致。mysql> select * from performance_schema.session_variables where variable_name in ('character_set_connection','collation_connection','character_set_database','character_set_results','character_set_client');+--------------------------+--------------------+| VARIABLE_NAME            | VARIABLE_VALUE     |+--------------------------+--------------------+| character_set_client     | latin1             || character_set_connection | utf8mb4            || character_set_database   | utf8mb4            || character_set_results    | latin1             || collation_connection     | utf8mb4_0900_ai_ci |+--------------------------+--------------------+5 rows in set (0.00 sec)

2)只用来设置字符集,不能定义具体的排序规则名称,也就是排序规则名称都是字符集对应的默认排序规则名称。这点从以上例子就可以看出来。

5. collate 子句

collate 语句强制指定排序规则,优先级最高。也就是显式指定 collate 会覆盖已有的排序规则。

这里涉及到单个字符串以及字符串拼接的排序规则问题。

显式的指定排序方式

-- 示例表 c1,mysql> create table c1 (n char(1));Query OK, 0 rows affected (0.06 sec)-- 插入示例数据,英文大小写字母乱序插入mysql> insert into c1 with recursive a(x,y) as(   select 65,97 union all select x+1,y+1 from a where x<90)select char(x using ascii) x from aunion allselect char(y using ascii) y from a order by rand();Query OK, 52 rows affected (0.02 sec)Records: 52  Duplicates: 0  Warnings: 0

改变 order by 的排序规则。

-- 原有排序结果mysql> select n from c1 order by n  desc limit 6;+------+| n    |+------+| Z    || z    || y    || Y    || x    || X    |+------+6 rows in set (0.00 sec)-- collate 显式指定后,排序结果。mysql> select n from c1 order by n  collate utf8mb4_0900_bin desc limit 6;+------+| n    |+------+| z    || y    || x    || w    || v    || u    |+------+6 rows in set (0.00 sec)

用于具体的列别名

mysql> select n collate utf8mb4_bin as n from c1 order by n  desc limit 6;+------+| n    |+------+| z    || y    || x    || w    || v    || u    |+------+6 rows in set (0.01 sec)

用于聚合函数

mysql> select max(n) n from c1;+------+| n    |+------+| Z    |+------+1 row in set (0.00 sec)-- 强制collate结果mysql> select max(n collate utf8mb4_bin) n from c1;+------+| n    |+------+| z    |+------+1 row in set (0.00 sec)

或者用于 where,group by,having 等等。用于统计排序方式的强制性指标比如要在 where 条件里过滤字符串,where a = 'a',那此时是用 a 的排序规则,还是字符 'a' 的排序规则,这里就涉及到一个排序规则的强制性指标。MySQL 的排序规则强制性指标值 从 0 到 6 一共 7 个。数字指标越小,优先级越高。以下为指标值说明:同时,为了便于大家理解,MySQL 提供了如何检测这个指标的函数 coercibility,举几个例子看下:示例:

-- collate 字句指标为 0mysql> select coercibility('a' collate utf8mb4_bin) as 'coercibility';+--------------+| coercibility |+--------------+|            0 |+--------------+1 row in set (0.00 sec)-- 简单的文本指标为 4mysql> select coercibility('a') as 'coercibility';+--------------+| coercibility |+--------------+|            4 |+--------------+1 row in set (0.00 sec)-- 日期指标为 5mysql> select coercibility(now()) as 'coercibility';+--------------+| coercibility |+--------------+|            5 |+--------------+1 row in set (0.00 sec)-- 系统常量指标为 3mysql> select coercibility(@@server_uuid) as 'coercibility';+--------------+| coercibility |+--------------+|            3 |+--------------+1 row in set (0.00 sec)

总结对于字符集的控制相关 SQL 就介绍的差不多了。主要举例介绍了 MySQL 字符集相关的处理 SQL 语句,比如设置客户端相关编码语句:SET NAMES/SET CHARSET;设置排序规则语句:COLLATE;给 MySQL 信号的 introducer 等。希望对大家有帮助。


关于 MySQL 的技术内容,你们还有什么想知道的吗?赶紧留言告诉小编吧!

想看更多技术好文,点个“在看”吧!

mysql设置了utf8mb4还是报错_第07期:有关 MySQL 字符集的 SQL 语句相关推荐

  1. mysql赋予权限的时候报错_想要远程连接MySQL,赋予root权限没用啊?一直报语法错误...

    转载,希望对你有帮助: 1. 3306端口是不是没有打开? 使用nestat命令查看3306端口状态: ~# netstat -an | grep 3306 tcp        0      0 1 ...

  2. Java代码读取MySQL数据,遇到‘0000-00-00’报错Value ‘0000-00-00‘ can not be represented as java.sql.Date

    报错 再使用Java代码读取MySQL数据的时候,读取date格式的数据,然后使用DateTimeFormatter格式化的时候突然在控制台发现了报错,Value '0000-00-00' can n ...

  3. mysql 2003报错_为什么不建议在 MySQL 中使用 UTF-8?

    正文 记得去年我在往MySQL存入emoji表情 时,一直出错,无法导入.后来找到办法 -- 通过把 utf8 改成 utf8mb4 就可以了,并没有深究. 一年后,我看到一篇文章讲到emoji文字占 ...

  4. mysql floor报错_【学习笔记】MYSQL的floor报错原理分析总结

    网上关于floor报错的文章很多,但都是利用语句,介绍原理的文章大多一笔带过,不过我终于找到一篇像样的原理文章,于是参考着来理解原理,参考的这个链接说的很详细了,但我仍然还有些不明白的地方,所以就研究 ...

  5. mysql赋予权限的时候报错_用grant命令为用户赋权限以后,登录时,出现:ERROR 1045 (28000)...

    ERROR 1045(28000)信息是因为权限的问题.这个ERROR分为两种情况: 第一种: ERROR 1045 (28000): Access denied for user 'root'@'l ...

  6. ubuntu安装mysql报错_在Ubuntu上安装mysql数据库和遇到的问题

    如果上面没有成功,而出现了这样的问题的话: Mysql ERROR 1045 (28000): Access denied for user 'root'@'localhost'(using pass ...

  7. mysql表中插中文报错_向mysql表中插入含有中文的数据时报错:[Err] 1366

    创建的表及插入语句如下: create table students (name varchar(25), class varchar(25), grade int); insert into stu ...

  8. mysql怎么建只读账号报错_如何创建只读MySQL用户?

    介绍 有时,您只需要创建一个用户就可以对数据库进行只读访问.用户可以查看或读取数据库中的数据,但不能对数据或数据库结构进行任何更改. 创建一个新的用户帐户 要为MySQL创建只读数据库用户帐户,请执行 ...

  9. mysql设置表名字为占位符_这可能是把MySQL存储引擎讲解的最清楚的一篇文章了

    存储引擎是MySQL的组件,用于处理不同表类型的SQL操作.不同的存储引擎提供不同的存储机制.索引技巧.锁定水平等功能,使用不同的存储引擎,还可以获得特定的功能. 使用哪一种引擎可以灵活选择,一个数据 ...

最新文章

  1. 村上春树 开始写作_如何克服对写作的恐惧并找到开始的动力
  2. linux 创建虚拟IP
  3. python中__name == '__main__'
  4. 1822. 数组元素积的符号
  5. Office Open XML学习(1)-创建excel文档,并向单元格中插入字符串
  6. Modelbuilder快速入门
  7. 干货 | 一文轻松了解NLP所有相关任务简介!
  8. CBV-2-CBV流程-view源码解析-面向对象-继承
  9. android 电影院订票系统 论文,电影院网上订票系统-毕业论文.doc
  10. 前端pdf禁止下载功能
  11. Encountered a duplicated sql alias [ID] during auto-discovery of a native-sql query; nested exceptio
  12. 一周上手flutter
  13. Linux与git使用引导(git rm 与rm命令)
  14. django 开发(一) mezzanine源码+ubuntu实现CMS Demo
  15. Word如何让不同页显示不同的页码,页眉
  16. 画论25 黄休复《益州名画录》
  17. 形状类似小于等于号的符号是啥
  18. 使用 Win32 API 枚举应用程序
  19. 八大行业Hadoop大数据应用回顾和展望
  20. php中水仙花数的求法,php 求水仙花数优化

热门文章

  1. PIE SDK点元素的绘制
  2. 【博客美化】评论带头像,且支持旋转
  3. 【iOS报错】“The operation couldn’t be completed (LaunchServicesError erro
  4. 与servlet Api 的集成
  5. 在持续交付中加入自动化验收测试支持
  6. 前端性能优化之jQuery按需加载轮播图
  7. 选择排序-直接选择排序
  8. Linux基础命令---修改用户信息usermod
  9. Linux(RHEL7.0)下安装nginx-1.10.2
  10. More than React(一)为什么ReactJS不适合复杂交互的前端项目?