免责声明:我知道这个问题之前已被问过一百次了,但我只是想检查一下,在我开始编写/获取大量代码之前,我可能已经错过了一个更简单的解决方案.
我们的软件使用最初为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类型列上使用它.
例:
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