【问题标题】:SQL Server 2012- Server collation and database collationSQL Server 2012-服务器排序规则和数据库排序规则
【发布时间】:2014-02-22 00:21:06
【问题描述】:

我安装了用于几个不同应用程序的 SQL Server 2012。我们需要安装其中一个应用程序,但该公司表示:

SQL 排序规则不正确,应该是:SQL_Latin1_General_CP1_CI_AS

您可以卸载 SQL Server 数据库引擎并在重新安装时选择正确的排序规则。

这家公司有什么可能的原因要更改数据库引擎本身的排序规则?

【问题讨论】:

  • 他们不专业,没有修复他们的软件以使用一系列排序规则,而是认为客户有过错?
  • tempDB 从服务器继承排序规则。如果您的应用程序数据库与服务器的排序规则不同,则临时表上的联接可能不起作用。也许这就是他们要求您在服务器范围内进行某种排序规则的原因。
  • @Damien_The_Unbeliever 供应商更有可能是无知而不是不专业。排序规则(和编码 / Unicode / ASCII / 等)对于大多数人来说是一个非常混乱的领域,即使对于一些相信他们理解它们的人来说也是如此。我在下面的answer 中解释了问题可能出在哪里。

标签: sql-server sql-server-2012 collation


【解决方案1】:

是的,您可以在数据库级别设置排序规则。为此,以下是一个示例:

    USE master;
    GO
    ALTER DATABASE <DatabaseName>
    COLLATE SQL_Latin1_General_CP1_CI_AS;
    GO

【讨论】:

    【解决方案2】:

    即使在使用以下查询创建数据库后,您也可以更改数据库排序规则

    USE master;
    GO
    ALTER DATABASE Database_Name
    COLLATE Your_New_Collation;
    GO
    

    有关数据库排序规则的更多信息Read here

    【讨论】:

    • 谢谢 - 是的,我就是这么想的,尽管我看不出有什么令人信服的理由来说明他们为什么希望在数据库引擎本身上更改排序规则?有什么想法吗?
    • 没问题,不知道为什么他们有这个奇怪的要求,只要应用程序数据库具有正确的排序规则设置,他们的应用程序应该可以正常运行。 The Company 您已经提到如果供应商的应用程序将使用此数据库并且他们要求您这样做,请稍后再做,如果他们的应用程序出现任何问题,他们可以将全部归咎于您的排序规则设置。现在只需使用此Alter Database 进行排序更改,但如果他们仍然反对它,那么就按照他们的要求去做吧:) 从经验中谈起。
    • 好的,所以我得到了他的回复:反过来,在附加数据库时,您需要新的 SQL 实例排序规则来匹配旧的 SQL 排序规则。排序规则用于数据库的功能,而不仅仅是在创建时设置的东西。
    • 对,这是实例级别的排序规则类型,这意味着您的所有系统数据库也将具有这种特定的排序规则类型。这可能是因为他们的应用程序需要特定的排序规则才能正常工作。在这种情况下,您将需要安装一个新实例并选择所需的排序规则类型作为 sql server 实例的默认排序规则。并且更改实例的排序规则是相当复杂的过程read here,如果此答案对您有帮助,请接受它作为您的答案,谢谢
    【解决方案3】:

    这家公司有什么可能的原因要更改数据库引擎本身的排序规则?

    其他两个答案是在数据库级别排序规则方面,而不是实例级别排序规则(即“数据库引擎本身”)。供应商想要一个高度具体的排序规则(例如,不仅仅是一个不区分大小写的排序规则)的最可能原因是,像大多数人一样,他们并不真正了解排序规则是如何工作的,但他们知道 当实例和数据库都有一个SQL_Latin1_General_CP1_CI_AS 的排序规则时,他们的应用程序可以工作(即没有出现排序规则冲突错误),这是他们的实例和数据库的排序规则(他们开发的app on),因为这是在以英语为语言的操作系统上安装时的默认排序规则。

    我猜他们可能有一些客户报告了他们不知道如何解决的问题,但将其范围缩小到那些没有SQL_Latin1_General_CP1_CI_AS 作为实例/服务器级别排序规则的实例。 Instance-level Collat​​ion不仅控制tempdb元数据(以及创建本地或全局临时表时未指定COLLATE关键字时的默认列Collat​​ion),这已经被其他人提到过,而且还控制变量的名称解析/参数、光标和GOTO 标签。即使他们不太可能使用GOTO 语句,他们肯定会使用变量/参数,并且可能足以使用游标。

    这意味着他们可能在以下一个或多个方面存在问题:

    1. 与临时表相关的排序规则冲突错误:

      tempdb 在实例的排序规则中并不总是意味着会有问题,即使 COLLATE 关键字从未在 CREATE TABLE #[#]... 语句中使用。只有在尝试合并或比较两个字符串时才会发生排序规则冲突。因此,假设他们创建了一个临时表并将其与数据库中的一个表一起使用,他们将需要在这些字符串列上加入,或将它们连接起来,或通过UNION 组合它们,或类似的东西。在这种情况下,如果两列的 Collat​​ions 不相同,就会发生错误。

    2. 意外行为:

      将表的字符串列与变量或参数进行比较将使用列的排序规则。鉴于他们要求您使用SQL_Latin1_General_CP1_CI_AS,该供应商显然希望进行不区分大小写的比较。由于临时表的字符串列(不是使用COLLATE 关键字创建的)采用实例的排序规则,如果实例使用二进制或区分大小写的排序规则,那么它们的应用程序将不会返回所有数据他们期待它回来。

    3. 代码编译错误:

      由于实例级排序规则控制变量/参数/游标名称的解析,如果它们的任何变量/参数/游标名称的大小写不一致,则尝试执行代码时会出现错误。例如,这样做:

      DECLARE @CustomerID INT;
      SET @customerid = 5;
      

      会得到以下错误:

      消息 137,第 15 级,状态 1,第 XXXXX 行
      必须声明标量变量“@customerid”。

      同样,他们会得到:

      消息 16916,第 16 级,状态 1,第 XXXXX 行
      名为“客户”的光标不存在。

      如果他们这样做:

      DECLARE customers CURSOR FOR SELECT 1 AS [Bob];
      OPEN Customers;
      

    这些问题很容易避免,只需执行以下操作:

    1. 在创建临时表(本地或全局)时,在字符串列上指定 COLLATE 关键字。如果不能保证数据库本身具有特定的排序规则,则使用 COLLATE DATABASE_DEFAULT 会很方便。但如果数据库的排序规则始终相同,那么您可以指定DATABASE_DEFAULT 或特定的排序规则。虽然我认为DATABASE_DEFAULT 在这两种情况下都有效,但也许这是更容易的选择。

    2. 标识符的大小写保持一致,尤其是变量/参数。为了更完整,我应该提到实例级元数据也受实例级排序规则的影响(例如登录名、数据库、服务器角色、SQL 代理作业、SQL 代理作业步骤等)。所以在所有领域都与套管保持一致是最安全的选择。


    假设供应商不了解排序规则的工作原理,我是否不公平?好吧,根据 O.P. 对 M.Ali 回答的评论:

    我从他那里得到了这样的回复:“反过来,你需要新的 SQL 实例排序规则来匹配旧的 SQL 排序规则,以便在将数据库附加到它时。排序规则用于数据库的运行,而不仅仅是一些东西它在创建时设置。”

    答案是“不”。这里有两个问题:

    1. 不,将数据库附加到新实例时,源实例和目标实例的排序规则不需要匹配。事实上,您甚至可以将系统 DB 附加到具有不同排序规则的 Instance,从而使附加的系统 DB 与 Instance 和其他系统 DB 不匹配。

    2. 不清楚最后一句中的“数据库”是指实际的数据库还是实例(有时人们使用术语“数据库”来指代整个 RDBMS)。如果它意味着实际的“数据库”,那么这完全无关紧要,因为手头的问题是实例级排序规则。但是,如果供应商指的是 Instance,那么虽然 Collat​​ion 确实用于正常操作(如上所述),但这仅表明对简单因果关系的认识,而不是实际理解。实际理解将导致执行那些简单的修复(如上所述),这样实例级排序规则就不是问题了。


    如果需要更改Instance的Collat​​ion,请看:

    Changing the Collation of the Instance, the Databases, and All Columns in All User Databases: What Could Possibly Go Wrong?

    有关使用排序规则 / 编码 / Unicode / 等的更多信息,请访问:

    Collations.Info

    【讨论】:

      猜你喜欢
      • 2011-04-06
      • 2014-11-25
      • 2011-04-08
      • 2011-05-05
      • 2019-03-07
      • 2011-10-15
      • 2012-06-08
      • 2010-10-07
      • 2020-12-16
      相关资源
      最近更新 更多