Sql server 如何在SQL Server数据库中使用UTF-8排序规则?

Sql server 如何在SQL Server数据库中使用UTF-8排序规则?,sql-server,utf-8,Sql Server,Utf 8,我已经将一个数据库从mysql迁移到SQL Server(politics),这是使用UTF8的原始mysql数据库 现在我读到SQLServer2008不支持utf8,这是一个笑话吗 SQL Server承载多个数据库,大部分是拉丁语编码的。由于迁移的db是用于web发布的,所以我希望保留utf8编码。我是否遗漏了一些内容,或者我需要在应用程序级别进行enc/dec操作?否!这不是玩笑 请看这里: 固定长度、nchar或nchar的字符数据类型 可变长度、nvarchar、Unicode数据,

我已经将一个数据库从mysql迁移到SQL Server(politics),这是使用UTF8的原始mysql数据库

现在我读到SQLServer2008不支持utf8,这是一个笑话吗

SQL Server承载多个数据库,大部分是拉丁语编码的。由于迁移的db是用于web发布的,所以我希望保留utf8编码。我是否遗漏了一些内容,或者我需要在应用程序级别进行enc/dec操作?

否!这不是玩笑

请看这里:

固定长度、nchar或nchar的字符数据类型 可变长度、nvarchar、Unicode数据,并使用Unicode UCS-2 字符集

还有这里:

较旧的UCS-2(2字节通用字符集)也是类似的 在版本2.0中被UTF-16取代的字符编码 Unicode标准于1996年7月发布


UTF-8不是字符集,它是一种编码。UTF-8的字符集是Unicode。如果要存储Unicode文本,请使用
nvarchar
数据类型

如果数据库使用UTF-8来存储文本,您仍然无法将文本作为编码的UTF-8数据输出,而是将其作为解码文本输出


您可以轻松地将UTF-8编码的文本存储在数据库中,但如果不将其存储为文本,则将其存储为二进制数据(
varbinary
)。

请注意,自Microsoft SQL Server 2016起,UTF-8受和的支持


附录2016-12-21:SQL Server 2016 SP1现在为所有版本的MS SQL(包括Standard和Express)启用Unicode压缩(以及大多数其他以前仅限企业使用的功能)。这与UTF-8支持不同,但如果目标是减少西文字母表的磁盘空间,则会产生类似的好处。

看来SQL Server 2019最终将支持这一点!

来自BOL:

UTF-8支持

完全支持广泛使用的UTF-8字符编码作为导入 或导出编码,或作为数据库级或列级排序规则 文本数据。在
CHAR
VARCHAR
数据类型中允许UTF-8,并且是 在创建对象的排序规则或将其更改为排序规则时启用 带有
UTF8
后缀

例如,
LATIN1\u GENERAL\u 100\u CI\u AS\u SC
to
LATIN1\u GENERAL\u 100\u CI\u AS\u SC\u UTF8
。UTF-8仅适用于Windows SQL中引入的支持补充字符的排序规则 服务器2012
NCHAR
NVARCHAR
仅允许UTF-16编码,并保留 不变

此功能可显著节省存储空间,具体取决于 正在使用的字符集。例如,更改现有列数据 使用UTF-8键入ASCII字符串,从
NCHAR(10)
CHAR(10)
启用排序功能,可将存储空间减少近50% 要求。这是因为
NCHAR(10)
需要22个字节 用于存储,而相同的Unicode需要12个字节 绳子

2019-05-14更新:

文档现在似乎正在更新,并在“MSSQL 2019”部分解释了我们的选项

2019-07-24更新:


-Microsoft高级项目经理关于引入对Azure SQL数据库的UTF-8支持的事宜

两个UDF来处理T-SQL中的UTF-8:

CREATE Function UcsToUtf8(@src nvarchar(MAX)) returns varchar(MAX) as
begin
    declare @res varchar(MAX)='', @pi char(8)='%[^'+char(0)+'-'+char(127)+']%', @i int, @j int
    select @i=patindex(@pi,@src collate Latin1_General_BIN)
    while @i>0
    begin
        select @j=unicode(substring(@src,@i,1))
        if @j<0x800     select @res=@res+left(@src,@i-1)+char((@j&1984)/64+192)+char((@j&63)+128)
        else            select @res=@res+left(@src,@i-1)+char((@j&61440)/4096+224)+char((@j&4032)/64+128)+char((@j&63)+128)
        select @src=substring(@src,@i+1,datalength(@src)-1), @i=patindex(@pi,@src collate Latin1_General_BIN)
    end
    select @res=@res+@src
    return @res
end

CREATE Function Utf8ToUcs(@src varchar(MAX)) returns nvarchar(MAX) as
begin
    declare @i int, @res nvarchar(MAX)=@src, @pi varchar(18)
    select @pi='%[à-ï][€-¿][€-¿]%',@i=patindex(@pi,@src collate Latin1_General_BIN)
    while @i>0 select @res=stuff(@res,@i,3,nchar(((ascii(substring(@src,@i,1))&31)*4096)+((ascii(substring(@src,@i+1,1))&63)*64)+(ascii(substring(@src,@i+2,1))&63))), @src=stuff(@src,@i,3,'.'), @i=patindex(@pi,@src collate Latin1_General_BIN)
    select @pi='%[Â-ß][€-¿]%',@i=patindex(@pi,@src collate Latin1_General_BIN)
    while @i>0 select @res=stuff(@res,@i,2,nchar(((ascii(substring(@src,@i,1))&31)*64)+(ascii(substring(@src,@i+1,1))&63))), @src=stuff(@src,@i,2,'.'),@i=patindex(@pi,@src collate Latin1_General_BIN)
    return @res
end
CREATE函数UcsToUtf8(@src nvarchar(MAX))将varchar(MAX)返回为
开始
声明@res varchar(MAX)='',@pi char(8)='%[^'+char(0)+'-'+char(127)+']%',@i int,@j int
选择@i=patindex(@pi,@src-collate-Latin1\u-General\u-BIN)
而@i>0
开始
选择@j=unicode(子字符串(@src,@i,1))
如果@j0选择@res=stuff(@res,@i,3,nchar((ascii(substring(@src,@i,1))&31)*4096+((ascii(substring(@src,@i+1,1))&63)*64+(ascii(substring(@src,@i+2,1))&63)),@src=stuff(@src,@i,3,'.'),@i=patindex(@pi,@src-collate-1\u-General\u-BIN)
选择@pi='%[€-?]',@i=patindex(@pi,@src-collate-Latin1\u-General\u-BIN)
当@i>0选择@res=stuff(@res,@i,2,nchar((ascii(substring(@src,@i,1))&31)*64)+(ascii(substring(@src,@i+1,1))&63)),@src=stuff(@src,@i,2,'.'),@i=patindex(@pi,@src-collate 1\u-General\u-BIN)
返回@res
结束

Ok。mssql客户端能否转换到外部UTF8世界?
mssql客户端
可以是一切。Java、.NET、C、PHP等。。。客户端是什么意思?客户端:php下的sqlsrv扩展。Robert在这里说:“我的明文是:,将评估并发布结果。您好,再次对延迟表示抱歉,但感谢各位代表,在连接字符串中使用sqlsrv_connect(,数组(“CharacterSet”=>“UTF-8”)…工作正常。PDO已退出,对吗?感谢您的输入。关于这方面还有更多需要了解的内容,例如,我无法理解这一点。“UTF8的字符集是Unicode”?UTF8不是比Unicode宽很多吗?用Unicode与UTF8保存Dauðalogn会得到不同的结果:(EF-BB-BF)44 61 75 C3 B0 61 6C 6F 67 6E vs\u0044\u0061\u0075\u00f0\u0061\u006c\u006f\u0067\u006e@user247245:UTF-8是编码,Unicode是字符集。UTF-8是保存Unicode的一种方法。用于表示Unicode的是字符串文字中使用的转义码,这通常不是将Unicode表示为文件的方式。UTF-32将e直接从未编码到文件格式的最接近的翻译,其中每个字符代码保存为32位数字。请解释一下为什么上面示例中的第三个字母在UTF8中表示为C3 B0,在unicode中表示为F0。谢谢您的帮助。@user247245:8到11位之间的字符代码编码为
110xxxxx10xxxxxx
在UTF-8中(其中
x
表示数据位),因此字符代码
F0
0001110000
为11位)被编码为
11000011 10110000
(将
00011
从字符代码放在第一个字节,将
110000
放在第二个字节)哪一个是
c3b0
。但不是OPENQUERY?我想知道这是否就是我的原因