目录

正确认识SQL Server的字符集

SQL Server作为一个国际化产品,支持多语言环境。在SQL Server中,字符集被称为排序规则(即Collation)。排序规则不仅影响记录行的sort顺序,还影响中文显示是否乱码等。在SQL Server中,排序规则可在3处地方设置:

服务器级别 =>instances 
db库级别 =>databases 
表列级别 =>columns

instancesdatabasescolumns

上图所示为SQL Server默认情况下对Collation继承的方式。

即在SQL Server软件安装时我们可设置服务器级别的排序规则,也就是instances的排序规则。如下所示是使用T-SQL查询当前instances的排序规则信息:

--查询当前SQL Server服务器的排序规则
SELECT SERVERPROPERTY(N'Collation')
--------------------------------------------------
Chinese_PRC_CI_AS

当然你也可以使用SSMS查看服务器属性: 

若在创建databases时我们未指定排序规则,databases则会使用instances的排序规则。如下所示是通过sql代码查询或修改SQL Server中databases的排序规则信息:

--在创建database时指定排序规则:SQL_Latin1_General_CP1_CI_AS
USE master;
GO CREATE DATABASE mydb
COLLATE SQL_Latin1_General_CP1_CI_AS
GO --通过目录视图sys.databases查询databases的排序规则
SELECT
name,
collation_name
FROM sys.databases
WHERE name = N'mydb';
-------------------------------------------------
mydb SQL_Latin1_General_CP1_CI_AS --修改现有databases的排序规则
ALTER DATABASE mydb
COLLATE Chinese_PRC_CI_AS

而表中的列(columns)默认情况是继承databases的排序规则(除非在创建表时对列的排序规则进行指定),我们可通过目录视图sys.columns查询表中columns的排序规则信息。

这里需注意:SQL Server的排序规则只影响字符型的列,如char, varchar, text, nchar, nvarchar, ntext,因此目录视图sys.columns中非字符型的排序规则显示为NULL

--注意:只有字符型的列才会显示排序规则信息,非字符型的显示为NULL
SELECT name, collation_name
FROM sys.columns
where collation_name is NOT NULL

选择合适的SQL Server字符集

在安装SQL Server时,你可能困惑应该选择哪种字符集,SQL Server或者Windows的。官方推荐使用SQL Server的字符集,而非Windows的字符集。原因是,SQL Server字符集是基于Windows衍生出来的,同时保证SQL Server版本间的兼容性, 如SQL Server 2014可使用的字符集比2008多

--查看当前SQL Server支持的排序规则
SELECT * from ::fn_helpcollations()

注意字符集的名字缩写与对应的的描述,如CI表示不区分大小写、

错误使用SQL Server的字符集

我们不难理解:只需保持SQL Server中3处字符集设置的地方:instances、databases、columns设置一致即是正确的使用方式。

那么当SQL Server中instances与databases对排序规则设置不一致时,将直接导致临时表#或##不能正常使用(临时表的列默认继承tempdb的排序规则,而tempdb则继承了instances的排序规则)。

/*
注意:
这里mydb的字符集是SQL_Latin1_General_CP1_CI_AS,
而instance的字符集是Chinese_PRC_CI_AS
*/
USE mydb;
GO --在mydb中创建一张表collation_test
CREATE TABLE collation_test (hyper varchar(10));
GO --创建临时表collation_temp
CREATE TABLE #collation_temp (hyper varchar(10));
GO

连接查询上述临时表的内容时,将出现如下报错信息:

--查询报错
SELECT *
FROM collation_test l
LEFT JOIN #collation_temp c
ON l.hyper = c.hyper;
--------------------------------------------
Msg 468, Level 16, State 9, Line 4
无法解决 equal to 运算中 "Chinese_PRC_CI_AS" 和 "SQL_Latin1_General_CP1_CI_AS" 之间的排序规则冲突。

其根本原因是由于表collation_test与临时表#collation_temp中列的排序规则不一致。虽然可以通过以下2种方式继续使用临时表,但并不推荐。如下通过指定select表中列的排序规则,继续使用上述两张表。

--方式1:
--注意指定表collation_test使用排序规则COLLATE Chinese_PRC_CI_AS
SELECT *
FROM collation_test l
LEFT JOIN #collation_temp c
ON l.hyper COLLATE Chinese_PRC_CI_AS = c.hyper
-------------------------------------------------------

第二种解决方法则是在创建表时指定列的排序规则

--方式2
USE mydb;
GO --注意指定了列的排序规则:COLLATE Chinese_PRC_CI_AS
CREATE TABLE collation_Wang
(hyper varchar(10) COLLATE Chinese_PRC_CI_AS); --保持列的排序规则一致即可正常使用临时表#collation_temp
SELECT *
FROM collation_wang w
LEFT JOIN #collation_temp c
ON w.hyper = c.hyper
-------------------------------------------------------

同时instances的排序规则设置会影响SQL Server数据的导入导出功能。

通常我们遇到的另一个问题是:通过SSMS(即SQL Server Management Studio)插入(insert)的中文,在查询时显示乱码(即问号?)。

--在上述表collation_test插入中文
INSERT INTO collation_test VALUES ('东') --查询表collation_test的记录
select * from collation_test

查询显示乱码: 

这当然是由于表collation_test上hyper列的字符集设置不正确所导致的。但若你有幸在表上使用了nvarchar等类型,那么当出现上述乱码时,也许你还可以使用如下临时方式补救:

/*
注意:
数据库mydb依旧是使用错误的排序规则:SQL_Latin1_General_CP1_CI_AS,
但是表collation_nvarchar使用了nvarchar类型,而非varchar
*/
USE mydb;
GO
CREATE TABLE collation_nvarchar (hyper nvarchar(10));
GO --临时处理方式
INSERT INTO collation_nvarchar VALUES (N'东'); --错误插入方式
INSERT INTO collation_nvarchar VALUES ('东'); --查询表collation_nvarchar的记录
select * from collation_nvarchar

综上述,我们应尽可能的正确设置SQL Server排序规则: 
1. 正确的设置SQL Server排序规则 ,保持instances、databases、columns中3处排序规则一致,推荐使用Chinese_PRC_CI_AS 
2. 尽可能使用nvarchar等Unicode类型,而非varchar类型

参考资料

    1. Setting and Changing the Database Collation 
      https://msdn.microsoft.com/en-us/library/ms175835(v=sql.105).aspx

    2. sys.columns (Transact-SQL) 
      https://msdn.microsoft.com/en-us/library/ms176106(v=sql.120).aspx

    3. Collation and International Terminology 
      https://msdn.microsoft.com/en-us/library/ms143726(v=sql.105).aspx

设置与使用SQL Server的字符集(Collation,即排序规则)的更多相关文章

  1. Windows分页文件设置不当导致SQL Server服务被终止

    Windows分页文件设置不当导致SQL Server服务被终止 文章说明 在正式开始验证和测试之前,先介绍Windows分页文件和SQL Server的动态内存管理.下面测试将分为两种测试场景:场景 ...

  2. 【.Net MVC4 connectionString设置】获取SQL server数据库的连接字符串

    第一步:创建向导文件 在桌面创建一个txt文件,并将文件后缀改成“.udl”.    第二步:选择“提供程序”tab页 双击新创建的“.udl”文件,进入后选择“提供程序”tab页,选择“Micros ...

  3. sql server 利用首字母拼音排序和笔画排序的语句

    --按笔画排序 select * from Student order by Sname COLLATE Chinese_PRC_Stroke_CS_AS_KS_WS --按字母拼音排序 select ...

  4. sql server针对字符串型数字排序(针对此字符串的长度不一致)

    对于不规则的字符串数字排序,无法按照数字大的大小排序的原因是,字符串数字在数据库中按照ASCII码排序,从字符的第一个数字对比,首先就会将为首个数字相同的排在一起,在从这些字符串里面对比第二个数字,如 ...

  5. Sql Server之ORDER BY不规则排序.如:中文月份排序

    ORDER BY CASE Month WHEN '一月' THEN 1 WHEN '二月' THEN 2 WHEN '三月' THEN 3 WHEN '四月' THEN 4 WHEN '五月' TH ...

  6. 【mysql】mysql创建数据库,基字符集 和 数据库排序规则 的对比选择

    1.一般选择utf8.下面介绍一下utf8与utfmb4的区别. utf8mb4兼容utf8,且比utf8能表示更多的字符.至于什么时候用,看你的做什么项目了,到https://www.cnblogs ...

  7. 解决sql "Compatibility_199_804_30003" 和 "SQL_Latin1_General_CP1_CI_AS" 之间的排序规则冲突。

    关联条件加  COLLATE Compatibility_199_804_30003

  8. 关于mysql创建数据库,基字符集 和 数据库排序规则 的对比选择

    1.一般选择utf8.下面介绍一下utf8与utfmb4的区别. utf8mb4兼容utf8,且比utf8能表示更多的字符.至于什么时候用,看你的做什么项目了,unicode编码区从1 - 126就属 ...

  9. SQL Server 与MySQL中排序规则与字符集相关知识的一点总结

    字符集&&排序规则 字符集是针对不同语言的字符编码的集合,比如UTF-8字符集,GBK字符集,GB2312字符集等等,不同的字符集使用不同的规则给字符进行编码排序规则则是在特定字符集的 ...

随机推荐

  1. 【阿里云IoT+YF3300】1.时代大背景下的阿里云IoT物联网的现状和未来

    “未来十到二十年,大家基本已经形成了一个共识,那便是新格局的奠定将由 AI 和物联网技术来支撑.放眼国内,在这些互联网巨头之中,未来真正成为竞争对手厮杀的,阿里和华为是首当其冲,在这两个领域双方分别暗 ...

  2. 让webStorm支持自动监听编译scss文件

    前提概要 今日,重装了两波系统,,,之前安装的各种环境都忘光了,重新又踩一次坑的感觉很不舒服,所以记录一下配置自动编译scss一路遇到的坑 一.webstrom run的时候控制台输出的错误中文提示乱 ...

  3. vue-cli目录结构介绍002

    总体框架 一个vue-cli的项目结构如下,其中src文件夹是需要掌握的,所以本文也重点讲解其中的文件,至于其他相关文件,了解一下即可. 文件结构细分 1.build——[webpack配置] bui ...

  4. 51nod 1099【贪心】

    思路: 我们可以思考对于仅仅两个元素来说,A,B; 先选A的话是会  A.b+B.a; 先选B的话是会 B.b+A.a; 所以哪个小哪个就放前面; #include <cstdio> #i ...

  5. GenericKeychain

    KeychainItemWrapper是apple官方例子“GenericKeychain”里一个访问keychain常用操作的封装类,在官网上 下载了GenericKeychain项目后,只需要把“ ...

  6. 第一篇 HTML5打包APP之VMware15安装MAC(MAC OS 10.13)(OS X 10.14)原版可升级最新可解锁macOS Unlocker3.0(OS X 10.13)

    1.1.2安装环境: 1.1.3所需资源: 1.1.4 Unlocker 3.0解锁 1.1.5 配置环境 1.1.6开始安装 1.1.7开启虚拟机进入MAC安装界面 1.1.8 macOS 10.1 ...

  7. JAVA团队开发手册 - 3. 开发流程

    开发流程 对于一个项目,最大的问题就是如何拆解为任务,分配到合适的人手里,并在有限的时间内完成它. 就像做建筑工程一样,其实做IT也是可以量化的,可能有的人砌砖砌得慢一些,有的人快一些. 但是我们把整 ...

  8. IP服务-5-网络时间协议

    NTP版本3(RFC1305)允许IP主机向一个通用的时钟源同步它们的日期和时间. 从设计上来说,大多数路由器和交换机都使用NTP客户端模式,根据NTP服务器所提供的时间来调整自己的时钟.NTP定义了 ...

  9. iOS UITableView 解决估算行高和指定行高的矛盾

    喜欢交朋友的加:微信号 dwjluck2013 1.一般来说 在iOS 中若UITableViewCell 固定行高, 会通过 - (CGFloat)tableView:(UITableView *) ...

  10. 记录一下在SpringBoot中实现简单的登录认证

    代码参考博客: https://blog.csdn.net/weixin_37891479/article/details/79527641 在做学校的课设的时候,发现了安全的问题,就不怀好意的用户有 ...