SQL SERVER的字符类型使用Unicode

这篇具有很好参考价值的文章主要介绍了SQL SERVER的字符类型使用Unicode。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  • 字符编码和排序规则
下面的讨论用到W、王和😀三个字符,以下是这三个字符的各种编码
SQL SERVER的字符类型使用Unicode

先看看不带N和带N的字符字面量各用什么编码,用Microsoft SQL Server Management Studio连接SQL SERVER 2022执行下面SQL语句:

select N'W' charact, convert (varbinary (20) , 'W') Not_N, convert (varbinary (20) , N'W') N union all
select N'', convert (varbinary (20) , '') , convert (varbinary (20) , N'')  union all
select N'😀' ,convert (varbinary (20) , '😀') , convert (varbinary (20) , N'😀') 

SQL SERVER的字符类型使用Unicode

可以确定,带N的是用UTF-16编码,而不带N的不是GB2312就是GBK或GB18030,默认字符类型的编码用的是ANSI,即本机操作系统的活动代码页,可在CMD控制台界面中输入chcp得到代码页编号,再查看CMD控制台的属性即可看到是GBK。

SQL SERVER的字符类型使用Unicode

而GBK是没有😀字符的,所以不带N的😀无法储存到GBK中,也就无法转换成对应的UTF-16,GBK将无法转换储存的字符一律用3F3F(即两个??问号)来储存。

GBK编码是在GB2312-80标准基础上的内码扩展规范,使用了双字节编码方案,其编码范围从8140至FEFE(剔除xx7F),共23940个码位,共收录了21003个汉字,完全兼容GB2312-80标准,支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字。GBK编码方案于1995年10月制定, 1995年12月正式发布,中文版的WIN95WIN98WINDOWS NT以及WINDOWS 2000、WINDOWS XP、WIN 7等都支持GBK编码方案。

再看在这个操作系统中建立的实例和数据库默认是什么排序规则

SELECT name, collation_name  FROM sys.databases where name='TestDB';  --显示TestDB的排序规则

SQL SERVER的字符类型使用Unicode正是这个Chinese_PRC_CI_AS排序规则会使不带N的字符字面量用GBK编码。

那问题来了,如果改用带UTF8的排序规则,字符字面量是不是就用UTF-8编码?我们再测试:

--新建排序规则为Chinese_PRC_90_CI_AS_SC_UTF8的数据库
CREATE DATABASE [UtfDB] CONTAINMENT = NONE COLLATE Chinese_PRC_90_CI_AS_SC_UTF8 WITH LEDGER = OFF 
GO
--再查询

select N'W' charact, convert (varbinary (20) , 'W') Not_N, convert (varbinary (20) , N'W') N union all
select N'王', convert (varbinary (20) , '王') , convert (varbinary (20) , N'王') union all
select N'😀' ,convert (varbinary (20) , '😀') , convert (varbinary (20) , N'😀')

SQL SERVER的字符类型使用Unicode

可以看到,不带N的列显示的是UTF-8编码,即数据库设定带UTF8排序规则,则不带N的字符字面量就用UTF-8编码。

  • char和varchar类型

根据微软官方文档对char和varchar类型的描述:“字符数据类型 char(大小固定)或 varchar(大小可变)。 从 SQL Server 2019 (15.x) 起,使用启用了 UTF-8 的排序规则时,这些数据类型会存储 Unicode 字符数据的整个范围,并使用 UTF-8 字符编码。 若指定了非 UTF-8 排序规则,则这些数据类型仅会存储该排序规则的相应代码页支持的字符子集。”,也就是说从2019版本开始,char和varchar在设定下可以储存为Unicode了。下面我们用SQL SERVER2022做个测试:

use TestDB
GO
SELECT name, collation_name  FROM sys.databases where name='TestDB';  --显示TestDB的排序规则
SQL SERVER的字符类型使用Unicode
--这个Chinese_PRC_CI_AS排序规则会使字符字面量用GBK编码。

create table tUnicode(
varc varchar(10), --默认的Chinese_PRC_CI_AS,
varcutf varchar(10) COLLATE Chinese_PRC_90_CI_AS_SC_UTF8  --指定带UTF8的排序规则
)

--插入以下六条记录

insert into tUnicode values('W',N'W') --英文字母
insert into tUnicode values('王',N'王') --汉字
insert into tUnicode values('😀',N'😀') --表情字符,其Unicode编码得三个字节表示
insert into tUnicode values(N'W',N'W') --英文字母
insert into tUnicode values(N'王',N'王') --汉字
insert into tUnicode values(N'😀',N'😀') --表情字符,其Unicode编码得三个字节表示

--查看结果

select *,
convert (varbinary (20) , varc) as varc_binary,
convert (varbinary (20) , varcutf) as varcutf_binary
from tUnicode;

SQL SERVER的字符类型使用Unicode

以此看出,varcutf列储存的是UTF-8,而varc列用的GBK储存不了要三个字节才能储存的😀表情字符。

  • nchar和nvarchar类型

  根据微软官方文档对char和varchar类型的描述:“字符数据类型 nchar(大小固定)或 nvarchar(大小可变)。 从 SQL Server 2012 (11.x) 起,使用启用了补充字符 (SC) 的排序规则时,这些数据类型会存储 Unicode 字符数据的整个范围,并使用 UTF-16 字符编码。 若指定了非 SC 排序规则,则这些数据类型仅会存储 UCS-2 字符编码支持的字符数据子集。”。文档说从2012版开始对nchar和nvarchar类型做了修改,我们用SQL SERVER 2022版测试一下:

create table tUnicode2(
    nvar nvarchar(10) ,  --默认的Chinese_PRC_CI_AS,
  nvarsc nvarchar(10) COLLATE Chinese_PRC_90_CI_AS_SC,
    nvar8 nvarchar(10) COLLATE Chinese_PRC_90_CI_AS_SC_UTF8,
)
--插入六条记录,插入的nvar列用的是不带N的字符字面量

insert into tUnicode2 values('W',N'W',N'W')
insert into tUnicode2 values('王',N'王',N'王')
insert into tUnicode2 values('😀',N'😀',N'😀')
insert into tUnicode2 values(N'W',N'W',N'W')
insert into tUnicode2 values(N'王',N'王',N'王')
insert into tUnicode2 values(N'😀',N'😀',N'😀')

select *,
convert (varbinary (20) , nvar) as nvar_binary,
convert (varbinary (20) , nvarsc) as nvarsc_binary,
convert (varbinary (20) , nvar8) as nvar8_binary
from tUnicode2;

SQL SERVER的字符类型使用Unicode

看到王字都是显示UTF-16编码,可以确定,不管用非SC(增补字符)还是用SC甚至UTF-8排序规则,其都是储存UTF-16编码。

  • 结论及应用

对于char和varchar类型,若排序规则带UTF8则储存的字符是UTF-8,否则就是ANSI(在我的本机是GBK)。而nchar和nvarchar类型,不管什么排序规则一律是UTF-16。在实际应用中,若要用Unicode编码,建议用nchar和nvarchar类型,不宜用UTF-8的char和varchar类型,因为不方便从数据表定义中查看哪些char和varchar类型的列是UTF-8的,默认的排序规则和设定带UTF8的排序规则在运算时会出现不兼容的错误提示。测试如下:

 文章来源地址https://www.toymoban.com/news/detail-858709.html

use TestDB
GO

create table tUnicode3(
varc varchar(10), --默认的Chinese_PRC_CI_AS,
varsc varchar(10) collate Chinese_PRC_90_CI_AS_SC,
varcutf varchar(10) COLLATE Chinese_PRC_90_CI_AS_SC_UTF8  --指定带UTF8的排序规则
)
GO

insert into tUnicode3 values('W','W',N'W')  --英文字母
insert into tUnicode3 values('','',N'')  --汉字

select *,
convert (varbinary (20) , varc) as varc_binary,
convert (varbinary (20) , varsc) as varsc_binary,
convert (varbinary (20) , varcutf) as varcutf_binary
from tUnicode3;

 

SQL SERVER的字符类型使用Unicode

select * from tUnicode3 where varsc = varc;

SQL SERVER的字符类型使用Unicode

select * from tUnicode3 where varsc = varcutf;

SQL SERVER的字符类型使用Unicode

这时就不得不用显式转换排序规则:

select * from tUnicode3 where varsc collate Chinese_PRC_90_CI_AS_SC_UTF8 = varcutf
and varsc collate Chinese_PRC_CI_AS= varc;

SQL SERVER的字符类型使用Unicode

且这种转换会有消耗,查看其执行计划,可以看到使用Convert函数转换:

SQL SERVER的字符类型使用Unicode

 

另外,char和varchar类型的ANSI和nchar和nvarchar类型的UTF-16是可以隐式转换的,转换不了就会乱码但不会出错。而UTF-8和UTF-16是完全兼容的,但用这两种编码的字符进行运算时会发生隐式转换。本人以前参与过一个仓储系统的维护,其货品条码主表的条码列用GBK的varchar类型,而引用此列的一些表却用nvarchar类型。虽说条码都是由ASCII码组成,完全兼容GBK和UTF-16,但两种编码的列在关联时会发生隐式转换,会有消耗,而这些SQL执行都很频繁,对系统很有影响。

 

到了这里,关于SQL SERVER的字符类型使用Unicode的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SQL Server数据类型

    目录 一、数值型数据 二、货币型数据 三、字符型数据 四、日期/时间数据类型 1、Bigint。 可以存放从-263到263-1范围内的 整型数据 。以bigint数据类型存储的每个值占用8个字节,共64位,其中63位用于存储数字,1位用于表示正负。 2、Int 。也可以写作integer,可以存储从-231到

    2024年02月04日
    浏览(35)
  • SQL Server 数据类型

    在SQL Server中,用来存储文本数据的数据类型主要有以下几种: 首先注意两点: // (1).Unicode是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案,是一个国际标准,用于计算机系统中文本的表示和处理。 以下是关于Unicode的一些关键点: 编码范围 : Unicode为每

    2024年01月17日
    浏览(42)
  • SQL server 数据类型转换

    在 SQL Server 中, CONVERT  和  PARSE  函数可以用于将一个数据值从一种数据类型转换为另一种数据类型,它们与  CAST  函数一样是 SQL Server 中常见的数据类型转换函数。 CONVERT 函数 CONVERT  函数用于将一个数据值从一种数据类型转换为另一种数据类型。它的基本语法如下: 其

    2024年02月11日
    浏览(44)
  • SQL Server截取字符串函数操作

    目录 1、SUBSTRING()函数 2、LEFT()函数  3、RIGHT()函数  4、CHARINDEX()函数  5、LEN函数 1、SUBSTRING()函数         含义:从指定位置开始截取指定数量的字符。         使用:SUBSTRING( 原字符 , 截取字符的起始位置 , 截取字符数量 )         举例:                 1、 截取字

    2024年02月01日
    浏览(56)
  • SQL Server对象类型(3)——视图(View)

    4.3.1. 视图概念 与Oracle中的视图类似,SQL Server中的视图也是一种虚的、通过一个查询定义的逻辑对象,主要用于集中、简化、定制用户需求,控住其底层表安全,以及应用系统提供向后兼容等方面。 -- 注:       1)上述内容中的“虚的”,表示视图本身并不实际包含和存储

    2024年02月09日
    浏览(34)
  • SQL Server对象类型(2)——索引(Index)(3)

    说完了簇索引,接下来我们再说说非簇索引,与Oracle中的普通B-tree索引类似。SQL Server中的非簇索引,首先,其也是通过一个B-tree结构进行组织和存储,该结构同样分为根节点/数据页(Root Node/Page)、中间节点/数据页(Intermediate Nodes/Pages)和叶子节点/数据页(Leaf Nodes/Pages),

    2024年02月11日
    浏览(44)
  • python 中文字符转换unicode及Unicode 编码转换为中文

    废话不多说 直接开干 知识点 decode 字节编码可decode为str encode 将字符串转换为bytes类型的对象 (即b为前缀, bytes类型), 即Ascll编码, 字节数组 encode(‘unicode-escape’)可将此str编码为bytes类型, 内容则是unicode形式 decode(‘unicode-escape’)可将内容为unicode形式的bytes类型转换为str 将一段

    2024年02月04日
    浏览(43)
  • 关于Sql server数据类型HierarchyID 数据类型用法和递归显示完整路径

    SQL Server 2008版本之后的新类型HierarchyID 不知道大家有没有了解, 该类型作为取代id, parentid的一种解决方案,让人非常惊喜。 官方给的案例浅显易懂,但是没有实现我想要的基本功能,树形结构中完整名称路径的展示。本文末尾是一个完整路径的样例,需要更多基本操作可以

    2024年03月13日
    浏览(41)
  • SQL SERVER日期与字符串之间的转换

    本文导读:在SQL Server数据库中,SQL Server日期时间格式转换字符串可以改变SQL Server日期和时间的格式,是每个SQL数据库用户都应该掌握的。下面主要就介绍一下SQL Server日期时间转字符串的相关知识 一、日期转换为字符串、日期格式 1、使用函数CONVERT: 2、参数 expression :是任

    2024年02月10日
    浏览(51)
  • 解决sql server 不支持variant的数据类型

    博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客👦🏻 《java 面试题大全》 🍩惟余辈才疏学浅,临摹之作或有不妥之处,还请读者海涵指正。☕🍭 《MYSQL从入门到精通》数据库是开发者必会基础之一~ 🪁 吾期望此文有资助于尔,即使粗浅难及深广,亦备添少许微薄

    2024年02月09日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包