【发布时间】:2015-12-15 06:09:12
【问题描述】:
SQL Server 中varchar 使用哪种编码?
我们可以动态改变varchar的编码吗?
【问题讨论】:
标签: sql-server varchar
SQL Server 中varchar 使用哪种编码?
我们可以动态改变varchar的编码吗?
【问题讨论】:
标签: sql-server varchar
聚会迟到了,但问题仍然非常中肯……
第一个问题是“SQL Server 中的 varchar 使用哪种编码?”。这是个好问题!
快速回答:取决于COLLATION(见下文)。对于最常见的COLLATIONs,例如默认的Latin1_General_CI_AI 或SQL_Latin1_General_CP1_CI_AS,ENCODING 将是Windows-1252。
但自 SQL Server 2019 以来,我们有 COLLATIONs 就像 Latin1_General_100_CI_AS_SC_UTF8 使用 UTF-8 ENCODING!
完整答案:
MSSQL Server 使用COLLATION 来确定@987654334@ 用于char/nchar/varchar/nvarchar 字段。因此,与很多人认为的不同,COLLATION 不仅仅是对数据进行排序和比较,还涉及ENCODING,因此:我们的数据将如何存储。
那么,我们如何知道我们的排序规则使用的编码是什么? 有了这个:
SELECT COLLATIONPROPERTY( 'Latin1_General_CI_AI' , 'CodePage' ) AS [CodePage]
--returns 1252
这个简单的 SQL 返回 Windows Code Page 对应的 COLLATION。 Windows Code Page 只不过是到 ENCODINGs 的另一个映射。对于 Latin1_General_CI_AI COLLATION 它返回 Windows Code Page 代码 1252 ,映射到 Windows-1252 ENCODING。
因此,对于带有Latin1_General_CI_AICOLLATION 的varchar 列,该字段将使用Windows-1252ENCODING 处理其数据,并且仅正确存储此编码支持的字符。
UTF-8
从 SQL Server 2019 开始,我们可以使用 CHAR/VARCHAR 字段并完全支持 UNICODE 使用 UTF-8 ENCODING!!!
来自微软的“char and varchar (Transact-SQL)”文档:
从 SQL Server 2019 (15.x) 开始,当启用了 UTF-8 的排序规则时 使用时,这些数据类型存储全范围的 Unicode 字符 数据并使用 UTF-8 字符编码。如果非 UTF-8 排序规则是 指定,则这些数据类型仅存储字符的子集 该排序规则的相应代码页支持。
因此,如果我们使用比 2019 年更早的 SQL Server,例如 SQL Server 2008 R2,我们需要使用前面介绍的方法检查 ENCODING。但是,如果我们使用 SQL Server 2019 或更高版本,并定义 COLLATION 像 Latin1_General_100_CI_AS_SC_UTF8,那么我们的字段将使用 UTF-8 ENCODING,这是迄今为止支持所有 UNICODE 字符的最常用和最有效的编码.
您可以在 char/nchar/varchar/nvarchar 字段中看到更详细的解释,涵盖 ENCODINGs,以及有关此答案的其他详细信息:https://stackoverflow.com/a/63637996/3395460
第二个问题是“我们可以动态更改 varchar 的编码吗?”。
你可以,虽然我看不出有什么好的理由。使用 ALTER TABLE,您可以更改整个表的 COLLATION,或者只是一个字段,因此,更改它的 ENCONDING(实际上您甚至可以更改整个数据库的排序规则)。
ALTER TABLE dbo.MyTable
ALTER COLUMN MyColumn VARCHAR(50) COLLATE Latin1_General_100_CI_AI_SC_UTF8
就是这样。但请记住,这些字段上的数据转换可能会导致数据丢失!
【讨论】:
排序规则在三个不同的级别定义,每个级别都覆盖前一个。
首先,您拥有服务器排序规则 - 这是您在安装实例时定义的排序规则,它会影响所有后续对象,除非在其他地方重新定义 第二个是数据库排序规则 - 这会覆盖服务器排序规则并影响数据库中的所有对象。 最后关闭表中的每一列都可以有自己的排序规则。
Select Convert (Varchar, ServerProperty('collation'));
Select name, collation_name
From sys.databases;
Select name, collation_name
From sys.columns
Where name = N'<ColumnName>' And Object_Id = Object_Id('<Table\ViewName>')
更改列的排序规则并不总是那么容易,因为您必须首先找到对其的所有引用This Script 可能会有所帮助。
Karasu CZ 对一件事是正确的 - NVarChar 解决了所有这些问题,因为 NVarChar 是免费的。但这不是你要求的!
【讨论】: