免责声明:我知道这个问题之前已经被问过一百次了,但我只是想检查一下在我继续编写/获取大量代码来做之前,我可能错过了一个更简单的解决方案。
我们的软件使用最初为 SQL Server 7 设计的数据库,因此,创建它的所有脚本都没有为任何字符列指定任何显式排序规则。相反,当数据库创建/恢复到 SQL Server 2000 或更高版本时,每一列都会继承数据库排序规则(这恰好是SQL_Latin1_General_CP1_CI_AS
因为这是 SQL Server 7 的默认设置)。
从理论上讲,这无关紧要,因为如果我们的数据库是在客户的服务器上从头开始创建的,它会继承客户的服务器排序规则(这通常是现代安装默认设置Latin1_General_CP1_CI_AS
),并且一切正常。但是,当他们向我们发送数据库备份或我们向他们发送数据库备份时,这种情况就会崩溃,并且每当代码尝试访问临时表等时,我们或他们都会收到可怕的排序规则不匹配错误。
我们已经尝试教育客户安装或重建他们的 SQL Server 实例以使用我们首选的排序规则,但当然这并不总是发生,而且并不总是可能的。
涉及创建新数据库和复制数据的解决方案对我们来说并不实用,我们需要一根“魔杖”,我们可以在实时数据库中挥动它以在不干扰数据的情况下就地纠正所有列。我正在考虑编写一个实用程序来执行此操作,但由于这将是一项相当大的工作,有没有人有任何更简单的建议?
一种选择是“证明”您的代码免受排序规则不匹配的影响。
您可以使用特殊排序规则“DATABASE_DEFAULT”来强制执行,而无需知道实际排序规则是什么。您可以在需要使用的临时表、表变量和系统表中的 char 类型列上使用它。
例子:
这也意味着当您的客户将他们的数据库迁移到具有另一种不同排序规则的新 SQL Server 机器上时,它也可以工作......
简短的回答是没有简单的方法。我过去也遇到过同样的问题。
我要说的是两件事,首先,当您的客户向您发送一个带有意外排序规则的数据库时,安装一个具有与其数据库匹配的默认排序规则的新 SQL 实例,并在其中使用它。
第二个是确保您的应用程序将与其他排序规则一起使用,然后是默认值(因为将来可能会更改)并且只要 SQL 服务器和数据库上的排序规则匹配就可以正常工作。然后很容易让客户安装具有与其数据库匹配的排序规则的 SQL 服务器,然后就可以工作了。
或者编写一个实用程序来更新数据库中的所有表等,但这可能比你想要的要多。
如果数据库中的所有列都具有相同的排序规则,那么它只会在进行跨数据库查询时给您带来问题(或者您的应用程序对排序顺序敏感)。
当您意识到加入临时表是跨数据库的时,问题就出现了,就像它们在 tempdb 中一样。不过,这很容易排序 - 只需确保临时表中的任何文本列都是使用
COLLATE database_default
指令显式创建的。这意味着将使用当前数据库的默认排序规则创建列,而不是使用 tempdb 的默认集合(与服务器的默认集合相同)。