免责声明:我知道这个问题之前已经被问过一百次了,但我只是想检查一下,在我继续编写/获取大量代码之前,我可能错过了没有更简单的解决方案。
我们的软件使用最初为 SQL Server 7 设计的数据库,因此,创建它的所有脚本都没有为任何字符列指定任何显式排序规则。相反,当一个数据库被创建/恢复到 SQL Server 2000 或更高版本时,每一列都会继承数据库排序规则(这恰好是SQL_Latin1_General_CP1_CI_AS
因为这是 SQL Server 7 的默认设置)。
从理论上讲,这不会有太大影响,因为如果我们的数据库是在客户的服务器上从头开始创建的,它会继承客户的服务器排序规则(通常是现代安装默认设置Latin1_General_CP1_CI_AS
),并且一切正常。但是,当他们向我们发送数据库备份,或者我们向他们发送数据库备份时,这种情况就会崩溃,并且每当代码尝试访问临时表等时,我们或他们都会遇到可怕的排序规则不匹配错误。
我们曾尝试教育客户安装或重建他们的 SQL Server 实例以使用我们首选的排序规则,但当然这并不总是发生,也不总是可能的。
涉及创建新数据库和复制数据的解决方案对我们来说并不实用,我们需要一个“魔杖”,我们可以在实时数据库中挥动它以在不干扰数据的情况下就地更正所有列。我正在考虑编写一个实用程序来做到这一点,但由于这将是一项艰巨的工作,有人有更简单的建议吗?
一种选择是“证明”您的代码防止排序规则不匹配。
您可以使用特殊的排序规则“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
Run Code Online (Sandbox Code Playgroud)
这也意味着,当您的客户将他们的数据库迁移到具有另一种不同排序规则的新 SQL Server 机器上时,它也能正常工作...
归档时间: |
|
查看次数: |
3603 次 |
最近记录: |