SQL Server 排序规则不匹配会减少应用程序可见的数据量吗?

use*_*615 2 sql-server collation

我们的一台服务器最近死了,它用错误的排序规则重建,所以它看起来如下:

  • SQL Server - SQL_Latin1_General_CP1_CI_AS
  • 主数据库 - SQL_Latin1_General_CP1_CI_AS
  • 模型数据库 - SQL_Latin1_General_CP1_CI_AI
  • msdb 数据库 - SQL_Latin1_General_CP1_CI_AI
  • 临时数据库 - SQL_Latin1_General_CP1_CI_AS
  • 每个用户数据库 - SQL_Latin1_General_CP1_CI_AI

数据库是可访问的,我的问题是:用户通过应用程序可见的数据是否会因为排序规则不匹配而受到限制?一些用户表示,即使数据库是从最近的备份中恢复的,他们也认为自己丢失了大量数据。

它是 Windows Server 2012 R2 上的 SQL Server 2008 R2 SP3(仅由于服务包而兼容)

谢谢

Sol*_*zky 6

用户通过应用程序可见的数据是否会因为排序规则不匹配而受到限制?

假设您说的是不会出错的场景(因为错误不会导致人们怀疑是否丢失了某些东西),而只是返回可能不是所有预期数据的数据,那么这取决于查询的方式完毕。如果以下所有条件都为真,那么是的,现在可以过滤掉一些以前没有的数据:

  1. 查询使用临时表(本地或全局)
  2. CREATE TABLE #TempTable语句中字符串列的排序规则没有通过COLLATE关键字显式指定排序规则
  3. 查询在字符串文字或局部变量上过滤临时表中至少一个这样的字符串列
  4. 该列中的数据与用于过滤的字符串(在文字或变量中)之间存在重音不匹配

意思是,以前有人可以执行:

SELECT * FROM #TempTable WHERE Name = 'a';
Run Code Online (Sandbox Code Playgroud)

并得到回包含以下行:A a À Á Â Ã Ä Å à á â ã ä å。使用新tempdb排序规则的相同查询现在将仅返回包含: 的行A a

此外,除了在面向用户的代码中发生的意外过滤之外,还有其他潜在问题等着您。如果master是不同的排序规则,那么系统级实体(例如数据库、登录名等)的名称将超出预期并且与系统的其余部分不同,并且可能导致类似于用户报告的奇怪行为。意思是,如果您在数据库和/或登录名和/或变量/参数/游标名称中有重音,并且具有可以工作的代码,因为它需要对重音不敏感的比较,那么/您的应用程序可能会体验到您的用户正在体验的东西(尽管可能需要一段时间才能注意到,甚至需要更长时间才能进行调试)。并且,假设所有四个系统 DB 都是相同的排序规则,并且在这种情况下,某些存储过程和视图在msdbJOIN 到master字符串列上并会中断。因此,这确实需要修复。

SO,因为它只是“不正确”的系统数据库(最好有mastermsdb匹配,因为有一些存储过程在它们之间加入并在它们的排序规则不匹配时出错),您应该只将那些更改回的预期排序规则SQL_Latin1_General_CP1_CI_AI。您可以通过使用SETUP.EXE /ACTION=Rebuilddatabase轻松完成此操作。它允许您只更改系统数据库,而不涉及用户数据库。

另请参阅 MSDN 文档:重建系统数据库设置或更改服务器排序规则

至少命令行应该看起来像(但都作为一行,或者你需要^在每一行的末尾使用,以便在下一行继续执行命令):

Setup /QUIET /ACTION=REBUILDDATABASE /INSTANCENAME={InstanceName}
      /SQLSYSADMINACCOUNTS={accountsToAddToSysadminRole} 
      /SQLCOLLATION=SQL_Latin1_General_CP1_CI_AI [/otherOptions]
Run Code Online (Sandbox Code Playgroud)

对于这种情况,您不需要使用未记录-q开关的其他建议用于sqlservr.exe. 该选项会重建所有数据库,无需对已经正确的数据库进行修改。您接触的越少(尤其是使用未记录的功能),您的境况就越好。