无法解决 equal to 运算中 "Chinese_PRC_CI_AS" 和 "SQL_Latin1_General_CP1_CI_AS" 之间的排序规则冲突。
什么是排序规则(collation)
关于SQL Server的排序规则,估计大家都不陌生,在创建数据库时我们经常要选择一种排序规则(conllation),一般我们会留意到每一种语言的排序规则都有许多种,比如标准大陆简体中文Chinese_PRC的排序规则就有数十种之多
这些排序规则有什么作用呢?让我们先来看看MS官方的解释:
排序规则指定了表示每个字符的位模式。它还指定了用于排序和比较字符的规则。排序规则具有下面的特征:
- 语言
- 区分大小写
- 区分重音
- 区分假名
比如在SQL Server 2005中,排序规则名称由两部份构成,比如 Chinese_PRC_CI_AI_WS
前半部份是指本排序规则所支持的字符集,如Chinese_PRC 指针对大陆简体字UNICODE的排序规则。
后半部份即后缀的含义如下:
_BIN
指定使用向后兼容的二进制排序顺序。_BIN2
指定使用 SQL Server 2005 中引入的码位比较语义的二进制排序顺序。_Stroke
按笔划排序_CI(CS)
是否区分大小写,CI不区分,CS区分_AI(AS)
是否区分重音,AI不区分,AS区分_KI(KS)
是否区分假名类型,KI不区分,KS区分_WI(WS)
是否区分全半角,WI不区分,WS区分
既然排序规则如此复杂,那么应用了不同排序规则的列之间默认情况下便不能进行Union、Join、Like等equal操作了,于是便有了排序规则(collation)冲突。
排序规则(collation)冲突
我们知道,SQL Server 从2000 开始,便支持多个排序规则。SQL Server 2000 的数据库可使用除默认排序规则以外的其他排序规则。此外,SQL Server 2000 还支持为列专门制定排序规则。
这样一来,我们在写跨表、跨数据库、跨服务器操作的T-SQL时,如果equal的字段排序规则不同,便会发生排序规则冲突。
比如我们先见两个结构相同的表,但字段的排序规则不同:
-- 1. Create TableA.
CREATE TABLE TagsTableA
(
TagName NVARCHAR(64) COLLATE Chinese_PRC_BIN
)
-- 2. Create TableB.
CREATE TABLE TagsTableB
(
TagName NVARCHAR(64) COLLATE Chinese_PRC_CI_AS
)
当表建好之后执行:
-- 3. Try to join them
SELECT * from TagsTableA A INNER JOIN TagsTableB B on A.TagName = B.TagName
便会出下类似下面的问题:
无法解决 equal to 操作中 "Chinese_PRC_BIN" 和 "Chinese_PRC_CI_AS" 之间的排序规则冲突。
常见的场景——临时表
我们知道,SQL Server的临时表是保存在Tempdb数据库中的。而使用临时表的数据库与临时表的排序规则(conllation)不一定相同。所以,当Tempdb的排序规则与当前使用临时表的数据库排序规则不同时,便会出现排序规则冲突。
一般来说,我们在创建临时表时可能不会注意到排序规则,从而留下排序规则冲突的隐患。
比如Openlab V4.0的Blog模块中的一个存储过程,便有着这种隐患:
/****** 对?象ó: StoredProcedure [blogs].[up_CreateGetTagIds] 脚本日期: 01/20/2010 19:10:32 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO /*
RETURN VALUES:
Ids
*/
-- =============================================
-- Author: <Lance Zhang>
-- Create date: <2010-01-06>
-- Description: <Make sure all the tag EXISTS in DB, and then get their ids.>
-- 1. Create Temp Table.
-- 2. Insert TagNames into Temp Table.
-- 3. Add new Tags to [Categories] from query Temp Table.
-- 4. Batch Get All Tag Ids from [Categories].
-- 5. Clear and drop Temp Table.
-- =============================================
ALTER PROCEDURE [blogs].[up_CreateGetTagIds]
(
@BlogId INT,
@TagNames XML
)
AS
BEGIN
/******************************* SET CONFIG *************************************************/
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SET NUMERIC_ROUNDABORT OFF /******************************* DECLARE VARIABLE *************************************************/ /********************************BEGIN TRANSATION**********************************************/ BEGIN TRY BEGIN TRANSACTION; -- 1. Create Temp Table.
CREATE TABLE #TagsTable
(
TagName NVARCHAR(64)
) -- 2. Insert TagNames into Temp Table.
INSERT INTO
#TagsTable
SELECT
TG.Tags.value('@i','NVARCHAR(64)') AS TagName
FROM
@TagNames.nodes('/ts/t') TG(Tags) -- 3. Add new Tags to [Categories] from query Temp Table.
BEGIN
INSERT INTO
[Categories]
(
[BlogId]
,[ParentId]
,[CategoryType]
,[CategoryName]
,[LoweredCategoryName]
,[Slug]
,[LoweredSlug]
,[Description]
,[CreatedDateUtc]
,[TotalEntities]
,[SortOrder]
,[State]
)
SELECT
@BlogId,
0, -- ParentId, 0 as default.
2, -- CategoryType, 2 as Post Tag.
TT.TagName,
LOWER(TT.TagName),
TT.TagName, -- Slug, use CategoryName as default.
LOWER(TT.TagName), -- LoweredSlug, use LoweredCategoryName as default.
'', -- Description, Empty as default.
GETUTCDATE(),
0, -- TotalEntities, 0 as default.
1, -- SortOrder of PostTags can always be 1.
1 -- State, 1 as Normal.
FROM
#TagsTable TT
WHERE
LOWER(TT.TagName) NOT IN
(
SELECT
C.[LoweredCategoryName]
FROM
[Categories] C WITH( UPDLOCK, HOLDLOCK )
WHERE
[BlogId] = @BlogId
AND [CategoryType] = 2 -- Post Tag.
) END -- 4. Batch Get All Tag Ids from [Categories].
BEGIN
SELECT
[CategoryId]
FROM
[Categories] C WITH(NOLOCK)
JOIN
#TagsTable TT
ON
C.[LoweredCategoryName] = LOWER( TT.TagName )
WHERE
C.[BlogId] = @BlogId
AND C.[CategoryType] = 2 -- Post Tag.
AND C.[State] = 1 -- 1 as Normal status.
END -- 5. Clear and drop Temp Table.
TRUNCATE TABLE
#TagsTable
DROP TABLE
#TagsTable COMMIT TRANSACTION;
RETURN 1 END TRY BEGIN CATCH
IF XACT_STATE() <> 0
BEGIN
ROLLBACK TRANSACTION;
RETURN -1
END
END CATCH
END
GO
常见的解决方案
知道了什么是排序规则冲突,我们接下来分析冲突的解决方案,以数据库级别的排序规则为例,一般来说,解决方案有下面几种
- 把SQL实例删了重建 ——大多数情况下等于没说-_-|||
- 修改数据库的排序规则 ——参考阿牛兄的这篇文章
- 在T-SQL中使用COLLATE DATABASE_DEFAULT来解决冲突 ——接下来主要讨论这个
COLLATE DATABASE_DEFAULT
Collate XXX 操作可以用在字段定义或使用时,它会将字段定义或转换成XXX 的排序规则格式。而Collate Database_Default 则会将字段定义或转换成当前数据库的默认排序规则,从而解决冲突。
比如在下面的代码中便使用了Collate Database_Default 来解决字段在equal操作中的排序规则冲突:
Insert into Security.Report (Name)
Select C.Path From SSRS.Catalog C
Where C.Path Collate Database_Default Like @ReportPath + '/%'
And C.Path Collate Database_Default Not In (Select Name From Security.Report R)
当然,在创建临时表时若对字段定义加上Collate Database_Default ,也可以方便地解决潜在的排序规则冲突,比如上一节中提到的存储过程,只要做如下修改即可。
-- 1. Create Temp Table.
CREATE TABLE #TagsTable
(
TagName NVARCHAR(64) COLLATE DATABASE_DEFAULT
)
结束语
对于专业的SQLer来说,排序规则的应用场景还有很多,例如利用排序规则特点计算汉字笔划和取得拼音首字母等等,更多信息,请查阅MSDN文档:http://msdn.microsoft.com/zh-cn/library/aa258237(en-us,SQL.80).aspx
引用: http://www.cnblogs.com/blodfox777/archive/2010/01/21/sqlserver-collation-conflict-and-solutions.html
无法解决 equal to 运算中 "Chinese_PRC_CI_AS" 和 "SQL_Latin1_General_CP1_CI_AS" 之间的排序规则冲突。的更多相关文章
- 无法解决 equal to 运算中 "Chinese_PRC_CI_AS" 和 "Chinese_PRC_90_CI_AI" 之间的排序规则冲突。的解决方法
在SQL SERVICE的查询的时候遇到了“无法解决 equal to 运算中 "Chinese_PRC_CI_AS" 和 "Chinese_PRC_90_CI_AI&q ...
- 无法解决 equal to 运算中 "Chinese_PRC_BIN" 和 "Chinese_PRC_CI_AS" 之间的排序规则冲突
无法解决 equal to 运算中 "Chinese_PRC_BIN" 和 "Chinese_PRC_CI_AS" 之间的排序规则冲突.问题如下图: 执行一下语 ...
- 无法解决 equal to 运算中 "Chinese_PRC_CI_AS" 和 "Latin1_General_100_CI_AS" 之间的排序规则冲突。
问题 操作临时表时提示如下排序规则冲突错误 sql ....忽略...sql ..... 无法解决 equal to 运算中 "Chinese_PRC_CI_AS" 和 " ...
- sql:无法解决 equal to 操作中 "Chinese_PRC_CI_AS" 和 "Chinese_Taiwan_Stroke_CI_AS" 之间的排序规则冲突。
--无法解决 equal to 操作中 "Chinese_PRC_CI_AS" 和 "Chinese_Taiwan_Stroke_CI_AS" 之间的排序规则冲 ...
- 无法解决 equal to 操作中 "SQL_Latin1_General_CP1_CI_AS" 和 "Chinese_PRC_CI_AS" 之间的排序规则冲突。
无法解决 equal to 操作中 "SQL_Latin1_General_CP1_CI_AS" 和 "Chinese_PRC_CI_AS" 之间的排序规则冲突 ...
- Sql 无法解决 equal to 运算中 "Chinese_PRC_CI_AS" 和 "Chinese_PRC_90_CI_AI" 之间的排序规则冲突
导致问题原因为创建时,表所使用的排序规则不一致 解决办法: 在对比条件后增加 collate Chinese_PRC_90_CI_AI 的转义即可 如: where test1.FieldName = ...
- "Chinese_PRC_CI_AS" 和 "Chinese_PRC_90_CI_AI" 之间的排序规则冲突问题
这个错误真是太恶心了.不过有解决办法,你问我哪来的?当然百度的咯! 示例: select a.workTypeDes from A a,B b where a.workTypeCode=b.work ...
- sql 用临时表时报错 "Chinese_PRC_90_CI_AI" 和 "Chinese_PRC_CI_AS" 之间的排序规则冲突
在用临时表关联数据库中的表做关联查询时,如果报这种情况的话,就要把临时表和关联的表的排序规则统一掉. LEFT JOIN #tsub ON #tsub.joinjarno collate Chines ...
- 无法解决 equal to 运算中 "Chinese_PRC_CI_AS" 和 "SQL_Latin1_General_CP1_CI_AS" 之间的排序规则冲突。
select * from a, b where a.Code=b.Code collate Chinese_PRC_CI_AS
随机推荐
- apache下ab.exe使用方法。。
自己在cmd中写了半天的路径也没有写对..最后网上的一个哥们告诉我说没有共同语言了...毛线啊 差距确实很大!大能猫死panda早晚干掉你,叫你丫整天嘲讽我! 比如我的ab.exe在D盘的wamp文件 ...
- IntentService 串联 按顺序执行(此次任务执行完才执行下一个任务)
IntentService与Service的最大区别就是前者依次执行,执行完当前任务才执行下一个任务,后者并发执行 在IntentService里面不写onCreate方法 MainActivity: ...
- ubuntu打开 txt 文件乱码
ubuntu12.04 gedit 打开 windows 分区中的 txt 文件乱码,是因为 ubuntu 和 windows 两个系统的编码不同.解决办法:终端里依次输入以下2 条命令即可: 代码: ...
- FireFox Prevent this page from creating addtional dialogs 火狐浏览器 设置 阻止此页面创建更多对话框
FireFox英文版本老弹出“Prevent this page from creating addtional dialogs”的确认框 FireFox english version alert ...
- setTimeOut(),和setInterVal()调用函数加不加括号!!!
直接在ready中调用其他方法,会提示缺少对象的错误,解决方法如下: 方法1. 应用jQuery的扩展可以解决这个问题. $(document).ready(function(){ $.extend( ...
- 计算系数 (codevs 1137) 题解
[问题描述] 给定一个多项式(ax + by)^k,给定a.b.k.n.m,请求出多项式展开后x^n y^m项的系数. [样例输入] 1 1 3 1 2 [样例输出] 3 [解题思路] 本题为NOIP ...
- 一个自定义的C#数据库操作基础类 SqlHelper
SqlHelper其实是我们自己编写的一个类,使用这个类目的就是让使用者更方便.更安全的对数据库的操作,既是除了在SqlHelper类以外的所有类将不用引用对数据库操作的任何类与语句,无须担心数据库的 ...
- R语言的日期运算
写hive SQL查询, 需要从导入的参数, 自动累加日期. 从而实现一个自动的,多个日期的统计过程 R语言的日期运算超级简单. > test<-Sys.Date() > test ...
- ARM时钟初始化
2440: S3C2440可以使用外部晶振(XTIpll)(默认为12MHZ)和外部时钟(EXTCLK)两种方式输入时钟信号.它由跳线OM[3:2]决定.S3C2440 默认的工作主频为12MHz(晶 ...
- 决策树的基本ID3算法
一 ID3算法的大致思想 基本的ID3算法是通过自顶向下构造决策树来进行学习的.我们首先思考的是树的构造从哪里开始,这就涉及到选择属性进行树的构造了,那么怎样选择属性呢?为了解决这个问题,我们使用统 ...