解决SQL Server /数据库排序规则不匹配的方法是否比更改每一列更简单?


8

免责声明:我知道这个问题已经被问过一百次了,但是我只是想检查一下,在继续编写并提供大量代码来实现这一目标之前,我没有错过一个更简单的解决方案。

我们的软件使用的数据库最初是为SQL Server 7设计的,因此,创建该数据库的所有脚本都不会为任何字符列指定任何显式排序规则。相反,当数据库创建/还原到SQL Server 2000或更高版本时,每一列都会继承数据库排序规则(恰好是SQL_Latin1_General_CP1_CI_AS因为这是SQL Server 7的默认设置)。

从理论上讲,这没什么大不了的,因为如果我们的数据库是从头开始在客户服务器上创建的,它将继承客户的服务器排序规则(通常是现代安装的默认设置Latin1_General_CP1_CI_AS),并且一切正常。但是,当他们向我们发送数据库备份,或者我们向他们发送数据库备份时,这种情况就无法解决了,无论何时代码尝试访问临时表等,我们或他们都会遇到可怕的排序规则不匹配错误。

我们已经尝试教育客户安装或重建他们的SQL Server实例以使用我们首选的排序规则,但是当然这并不总是会发生,而且也不总是可能。

涉及创建新数据库和复制数据的解决方案对我们而言实际上并不实用,我们需要一个“魔杖”,我们可以在实时数据库中挥动一下魔杖,以就地校正所有列而不会干扰数据。我正在考虑编写一个实用程序来执行此操作,但是由于这将是一项艰巨的任务,因此有人有更简单的建议吗?

Answers:


6

一种选择是“证明”您的代码以防排序规则不匹配。

您可以使用特殊的排序规则“ DATABASE_DEFAULT”来强制使用,而不必知道实际的排序规则是什么。您可以在临时表,表变量和系统表中需要使用的字符类型列上使用它。

例:

CREATE TABLE #Currency (CCY CHAR(3))
GO
INSERT #Currency VALUES ('GBP')
INSERT #Currency VALUES ('CHF')
INSERT #Currency VALUES ('EUR')
GO
SELECT Something
FROM myTable M JOIN #Currency C ON M.CCY = C.CCY --error!
GO
-- in join too
SELECT Something
FROM myTable M JOIN #Currency C ON M.CCY = C.CCY COLLATE DATABASE_DEFAULT --no error
GO
DROP TABLE #Currency
GO


CREATE TABLE  #Currency (CCY CHAR(3) COLLATE DATABASE_DEFAULT)
GO
INSERT #Currency VALUES ('GBP')
INSERT #Currency VALUES ('CHF')
INSERT #Currency VALUES ('EUR')
GO
SELECT Something
FROM myTable M JOIN #Currency C ON M.CCY = C.CCY --no error!
GO

DROP TABLE #Currency
GO

这也意味着,当您的客户端将其数据库迁移到具有另一个不同排序规则的新的SQL Server盒子时,它也可以工作...


2

简短的回答是没有简单的方法。我过去也遇到过同样的问题。

我要说的是两件事:首先,当客户向您发送具有意外排序规则的数据库时,使用默认排序规则匹配其数据库的情况安装新的SQL实例,并在其中使用它。

第二个是确保您的应用程序将与其他排序规则一起使用,然后默认设置(因为将来可能会更改)与其他排序规则一起使用,并且只要SQL Server和DB上的排序规则匹配即可正常工作。然后,让客户安装与数据库匹配的排序规则的SQL服务器就很容易了,然后就可以工作了。

或编写一个实用程序来更新数据库中的所有表等,如您所说,但这可能比您想要的还要多。


2

如果数据库中的所有列都具有相同的排序规则,则只会在进行跨数据库查询时对您造成问题(或者您的应用程序对排序顺序敏感)。

当您意识到联接到临时表是跨数据库的(就像它们在tempdb中一样)时,便出现了问题。不过,这很容易排序-只需确保临时表中的所有文本列都使用COLLATE database_default指令显式创建。这意味着将使用当前数据库的默认排序规则而不是tempdb的默认集合(与服务器的默认集合)创建该列。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.