无法解决排序规则冲突。

56

我已将我们的一个数据库(DB1)从SQL Server 2008迁移到2012,但运行存储过程时出现以下错误:

无法在相等操作中解决“SQL_Latin1_General_CP1_CI_AS”和“Latin1_General_CI_AS”之间的排序规则冲突

我使用以下命令更改了数据库的排序规则:

ALTER DATABASE [optimiser] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
ALTER DATABASE [optimiser] COLLATE SQL_Latin1_General_CP1_CI_AS
ALTER DATABASE [optimiser] SET MULTI_USER

但是每当存储过程运行时,我仍然会收到错误提示。我认为这是因为SP使用了连接到另一个数据库(GE的ihistorian)并且存在排序规则不匹配的问题。有没有解决此问题的方法。

在旧服务器上,DB1设置为 Latin1_General_CI_AS 并且可以正常工作。在新的位置上,DB的默认设置为 SQL_Latin1_General_CP1_CI_AS。是否值得将新服务器上的DB1排序规则更改回 Latin1_General_CI_AS

1个回答

124

关于字符集校对(collations)的事情是,尽管数据库有其自己的字符集校对(collation),每个表和每个列都可以有自己的字符集校对。如果没有指定,则采用其父对象的默认值,但也可以不同。

当您更改数据库的字符集校对时,它将成为所有新表和列的新默认值,但不会更改数据库中现有对象的字符集校对。您需要手动更改每个表和每个列的字符集校对。

幸运的是,互联网上有可用的脚本可以完成这项工作。我不会推荐任何一个,因为我没有试过,但以下是一些链接:

http://www.codeproject.com/Articles/302405/The-Easy-way-of-changing-Collation-of-all-Database

Update Collation of all fields in database on the fly

http://www.sqlservercentral.com/Forums/Topic820675-146-1.aspx

如果您需要在两个对象之间具有不同的字符集校对(collation),或者不能更改字符集校对,则仍然可以使用COLLATE命令在它们之间进行JOIN,并选择您想加入的字符集校对。

SELECT * FROM A JOIN B ON A.Text = B.Text COLLATE Latin1_General_CI_AS 

或者使用默认的数据库排序规则:

SELECT * FROM A JOIN B ON A.Text = B.Text COLLATE DATABASE_DEFAULT

1
如果是两个不同服务器上的两个独立数据库之间的 UNION 操作(通过链接服务器),该怎么办? - Fandango68
3
@Fandango68 你可以在UNION操作中的列名旁边添加COLLATE DATABASE_DEFAULT - Nenad Zivkovic
它也可以用于 where 条件中! - Geancarlo Murillo
我在语句中使用了它,它起作用了。 选择*从AAAA中,其中Item COLLATE DATABASE_DEFAULT不在(从DB.schema.BBBB中选择Code)。 - Kozbara

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接