SQL Server SQL\u Latin1\u General\u CP1\u CI\u AS能否安全地转换为Latin1\u General\u CI\u AS?
我们有一个遗留数据库,其中一些(旧的)列使用“SQL\u Latin1\u General\u CP1\u CI\u AS”,最近的更改使用了“Latin1\u General\u CI\u AS” 这是一种痛苦,因为联接需要额外的COLLATE语句才能工作 我想把一切都提到“拉丁语将军”上来。据我所知,它们或多或少都是相同的排序规则,我不会在这个过程中丢失数据 有人知道情况是否如此吗SQL Server SQL\u Latin1\u General\u CP1\u CI\u AS能否安全地转换为Latin1\u General\u CI\u AS?,sql,sql-server,collation,Sql,Sql Server,Collation,我们有一个遗留数据库,其中一些(旧的)列使用“SQL\u Latin1\u General\u CP1\u CI\u AS”,最近的更改使用了“Latin1\u General\u CI\u AS” 这是一种痛苦,因为联接需要额外的COLLATE语句才能工作 我想把一切都提到“拉丁语将军”上来。据我所知,它们或多或少都是相同的排序规则,我不会在这个过程中丢失数据 有人知道情况是否如此吗 SELECT * FROM ::fn_helpcollations() WHERE name IN ( 'SQ
SELECT * FROM ::fn_helpcollations()
WHERE name IN (
'SQL_Latin1_General_CP1_CI_AS',
'Latin1_General_CI_AS'
)
…给予
拉丁语1\u概述\u CI\u作为:
Latin1-General,不区分大小写,区分重音,不区分假名类型,不区分全半角
SQL拉丁语概述CP1 CI作为:
Latin1-General,不区分大小写,区分重音,不区分假名类型,Unicode数据不区分全半角,非Unicode数据的代码页1252上SQL Server排序顺序52
因此,从这一点,我可以推断所使用的代码页是相同的(Latin1 General=>1252),因此您应该不会遇到数据丢失-如果要更改转换后的排序顺序,可能是排序顺序-这可能无关紧要。此MSDN论坛上有更多信息: 其中指出: 如果排序规则是SQL\u Latin1\u General\u CP1\u CI\u AS或Latin1\u General\u CI\u AS,您应该不会看到什么区别,但两者都有比另一个更快或更慢的实例 Latin1_General_CI_AS:-Latin1 General,不区分大小写,重音- 敏感,不区分假名类型,不区分全半角 SQL\u Latin1\u General\u CP1\u CI\u AS:-Latin1 General,不区分大小写, 区分重音,不区分假名类型,Unicode不区分全半角 数据,非Unicode数据的代码页1252上的SQL Server排序顺序52
因此,在我看来,您不应该看到差异,特别是如果您的数据仅为a-z0-9,这里有一个更完整的答案: 这些排序规则之间的关键区别在于它们如何应用字符扩展规则。某些拉丁字符可以扩展为多个字符。在处理非unicode文本时,SQL_xxxx排序规则可能会忽略这些字符扩展,但会将它们应用于unicode文本。因此:当使用一种排序规则与另一种排序规则时,联接、排序和比较可能会返回不同的结果 例如: 在
Latin1_General_CI_AS
下,这两条语句返回相同的记录集,因为ß
扩展为ss
从MyTable3中选择*,其中注释='strasse'
从MyTable3中选择*,其中注释='straße'
当使用
SQL\u Latin1\u General\u CP1\u CI\u AS
时,上述语句返回不同的记录,因为ß
被视为不同于ss
的字符。如果您要更改数据库的排序规则,那么肯定有一些内容您应该知道,以便您可以进行相应的计划:
- 关于数据丢失的可能性:
字段都是Unicode,这是一个单一字符集,因此这些字段不会有任何数据丢失(这也包括同样存储为UTF-16 Little-Endian的XML字段)。存储对象/列/索引/etc名称的元数据字段都是NVARCHAR
,因此无需担心这些NVARCHAR
具有不同排序规则但不同排序规则之间具有相同代码页的字段不会有问题,因为代码页是字符集VARCHAR
具有不同排序规则并移动到不同代码页(更改排序规则时)的字段如果在新代码页中未表示所使用的任何字符,则可能会丢失数据。但是,这只是在物理更改特定字段(如下所述)的排序规则时出现的问题,在更改数据库的默认排序规则时不会发生VARCHAR
- 本地变量和字符串文本从数据库默认值获取排序规则。更改数据库默认值将更改用于局部变量和字符串文本的排序规则。但是更改数据库的默认排序规则不会更改该数据库中表中现有字符串列的排序规则。在将列与文字和/或变量进行比较或连接时,这通常不会导致任何问题,因为文字和变量由于排序规则的优先性将采用该列的排序规则。唯一的潜在问题是,对于值介于128-255之间的字符,可能会发生代码页转换,而这些字符在列排序规则使用的代码页中不可用
- 如果您希望列的谓词/比较/排序/连接等在更改数据库的默认排序规则时表现不同,则需要使用以下命令显式更改该列的排序规则:
确保指定与当前使用的数据类型完全相同的数据类型和ALTER TABLE[{TABLE_name}] ALTER列[{COLUMN_name}] {相同的数据类型} {相同的\u空\u或\u非空\u设置} COLLATE{name_of_Database_default_COLLATE};
/NULL
设置,否则,如果它们还不是默认值,则可以还原为默认值。之后,如果任何字符串列上有任何索引的排序规则刚刚更改,则需要重新生成这些索引非NULL
- 更改数据库的默认排序规则将更改特定于数据库的元数据的排序规则,例如
,sys.objects
,sys.columns
中的sys.indexes
字段,等等。根据局部变量或字符串文本过滤这些系统视图不会有问题,因为两侧的排序规则都会发生变化。但是,如果您将任何本地系统视图连接到字符串字段上的临时表,那么name