SQL Server中使用COLLATE关键字,解决排序规则不同的问题

在SQL Server中的字符类型都是有排序规则(collation)的,例如在下面的SQL语句中,我们建立了一个表变量@table_people,其中我们使用关键字COLLATE给列[Name]定义了排序规则"Chinese_PRC_CI_AS",也给列[Description]定义了排序规则"SQL_Latin1_General_CP1_CI_AS":

DECLARE @table_people TABLE
(
    [Name] NVARCHAR(50) COLLATE Chinese_PRC_CI_AS,
    [Description] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS,
    [Age] INT
)

INSERT INTO @table_people([Name],[Description],[Age])
VALUES 
(N'张三' COLLATE Chinese_PRC_CI_AS,N'这个人叫张三' COLLATE SQL_Latin1_General_CP1_CI_AS,31),
(N'李四' COLLATE Chinese_PRC_CI_AS,N'这个人叫李四' COLLATE SQL_Latin1_General_CP1_CI_AS,32),
(N'王五' COLLATE Chinese_PRC_CI_AS,N'这个人叫王五' COLLATE SQL_Latin1_General_CP1_CI_AS,33)

SELECT * FROM @table_people 

这段SQL代码可以成功执行,因为我们使用了COLLATE关键字为每一个字符串指定了相应的排序规则。

但是,如果我们对不同排序规则的字符串进行操作的时候就会报错,如下所示:

DECLARE @table_people TABLE
(
    [Name] NVARCHAR(50) COLLATE Chinese_PRC_CI_AS,
    [Description] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS,
    [Age] INT
)

INSERT INTO @table_people([Name],[Description],[Age])
VALUES 
(N'张三' COLLATE Chinese_PRC_CI_AS,N'这个人叫张三' COLLATE SQL_Latin1_General_CP1_CI_AS,31),
(N'李四' COLLATE Chinese_PRC_CI_AS,N'这个人叫李四' COLLATE SQL_Latin1_General_CP1_CI_AS,32),
(N'王五' COLLATE Chinese_PRC_CI_AS,N'王五' COLLATE SQL_Latin1_General_CP1_CI_AS,33)

SELECT * FROM @table_people WHERE [Name]=[Description]--Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Chinese_PRC_CI_AS" in the equal to operation.

上面的SQL语句,会在最后的SELECT语句报错:

Msg 468, Level 16, State 9, Line 14
Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Chinese_PRC_CI_AS" in the equal to operation.

由于我们在SELECT语句的WHERE条件中比较了列[Name]和列[Description]的值,但是[Name]和[Description]是两个排序规则不同的列,不能直接进行比较操作,所以我们要使用COLLATE关键字对排序规则进行转换后,才能进行比较:

DECLARE @table_people TABLE
(
    [Name] NVARCHAR(50) COLLATE Chinese_PRC_CI_AS,
    [Description] NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS,
    [Age] INT
)

INSERT INTO @table_people([Name],[Description],[Age])
VALUES 
(N'张三' COLLATE Chinese_PRC_CI_AS,N'这个人叫张三' COLLATE SQL_Latin1_General_CP1_CI_AS,31),
(N'李四' COLLATE Chinese_PRC_CI_AS,N'这个人叫李四' COLLATE SQL_Latin1_General_CP1_CI_AS,32),
(N'王五' COLLATE Chinese_PRC_CI_AS,N'王五' COLLATE SQL_Latin1_General_CP1_CI_AS,33)

--将列[Description]的排序规则转换为Chinese_PRC_CI_AS
SELECT * FROM @table_people WHERE [Name]=[Description] COLLATE Chinese_PRC_CI_AS

--将列[Name]的排序规则转换为SQL_Latin1_General_CP1_CI_AS
SELECT * FROM @table_people WHERE [Name] COLLATE SQL_Latin1_General_CP1_CI_AS=[Description]

由于现在我们使用COLLATE关键字对列[Name]和列[Description]的排序规则进行了转换,保证了SELECT语句WHERE条件中等号两边字符类型的排序规则是相同的,所以现在两个SELECT语句都不会报错,并成功返回了查询结果。

猜你喜欢

转载自www.cnblogs.com/OpenCoder/p/12411060.html