数据库排序规则的冲突(理解collateChinese_PRC_CI_AS)之前碰到了数据库排序规则冲突问题,即百度或者 Google的⽼话题: “⽆法解决 equal to操作中‘ sql_latin1_general_cp1_ci_as
’和‘ chinese_prc_ci_as’之间的排序规则冲突 ”。⼀般的⽅法,是在创建临时表或表连接的时候加上规则校勘语句 COLLATE “规则名”解决,如:
create table#example (
EXP_Name varchar (50) collate CHINESE_PRC_CI_AS NULL
)
select*
from A inner join B
on A.name=B.name collate Chinese_PRC_CI_AI_AS
或
select*
from A inner join B
on A.name collate Chinese_PRC_CI_AI_AS =B.name
但是,当⼀个数据库有很多触发器、存储过程或者函数需要修改的时候,这种⽅法显得不够显⽰,即使是将当中的内容导出成 .sql⽂件再⽤替换的⽅法修改,也是⽐较⿇烦的。曾经试图更改相关数据表的列,甚⾄数据库的排序规则,如:
ALTER DATABASE 数据库名 COLLATE排列规则,例如:
ALTER DATABASE dbexp COLLATE Chinese_PRC_CI_AI
ALTER DATABASE AutoUpgrade COLLATE Chinese_PRC_CI_AI
alter database database_name collate collate_name
这⾥为 Chinese_PRC_CI_AI_AS。
对于数据库字段,则有:
ALTER TABLE 表名 ALTER COLUMN 字段名 数据类型(长度) COLLATE 排列规则
例如:
ALTER TABLE Userinfo ALTER COLUMN name varchar (4) COLLATE Chinese_PRC_CI_AI
或者通过数据库的“属性 ->选项”更改排序规则, 但是,当整个数据库服务器的排序规则与我们所需的规则不⼀致时,这种⽅法也不能解决问题,这时候可以重装或修复数据库服务器。显然,修复要⽐重装的⼯作量⼩。⽤ CMD窗⼝进⼊安装⽬录,如插⼊光盘或者安装⽂件在某个⽬录下,输⼊如下语句运⾏:
start / /qb INSTANCENAME=MSSQLSERVER REINSTALL=SQL_Engine REBUILDDATABASE=1 SAPWD=test SQLCOLLATION=Chinese_PRC_CI_AI
其中,加粗部分是规则名,可以使别的规则。
现在附上关于⼀些排序规则描述
排序规则名称由两部份构成,前半部份是指本排序规则所⽀持的字符集。
如:
Chinese_PRC_CS_AI_WS
前半部份:指 UNICODE字符集, Chinese_PRC_指针对⼤陆简体字 UNICODE的排序规则。
排序规则的后半部份即后缀 含义:
_BIN ⼆进制排序
_CI(CS) 是否区分⼤⼩写, CI不区分, CS区分
_AI(AS) 是否区分重⾳, AI不区分, AS区分
_KI(KS) 是否区分假名类型 ,KI不区分, KS区分
_WI(WS) 是否区分宽度 WI不区分, WS区分
区分⼤⼩写 :如果想让⽐较将⼤写字母和⼩写字母视为不等,请选择该选项。
区分重⾳ :如果想让⽐较将重⾳和⾮重⾳字母视为不等,请选择该选项。如果选择该选项,⽐较还将重⾳不同的字母视为不等。
区分假名 :如果想让⽐较将⽚假名和平假名⽇语⾳节视为不等,请选择该选项。
区分宽度 :如果想让⽐较将半⾓字符和全⾓字符视为不等,请选择该选项。
我们在 create table 时经常会碰到这样的语句,例如: password nvarchar(10)collate chinese_prc_ci_as null ,那它到底是什么意思呢?不妨看看下⾯:
⾸先, collate 是⼀个⼦句,可应⽤于数据库定义或列定义以定义排序规则,或应⽤于字符串表达式以应⽤排序规则投影。
语法是 collate collation_name
collation_name :: ={windows_collation_name}|{sql_collation_name}
参数 collate_name 是应⽤于表达式、列定义或数据库定义的排序规则的名称。 collation_name 可以只是指定的 Windows_collation_name 或SQL_collation_name。
Windows_collation_name 是 Windows 排序规则的排序规则名称。参见 Windows 排序规则名称。
SQL_collation_name 是 SQL 排序规则的排序规则名称。参见 SQL 排序规则名称。
最浪漫的说早安方式下⾯简单介绍⼀下 排序规则:
什么叫排序规则呢? MS 是这样描述的: " 在 Microsoft SQL Server 2000 中,
字符串的物理存储由排序规则控制。排序规则指定表⽰每个字符的位模式以及存
储和⽐较字符所使⽤的规则。 "
在查询分析器内执⾏下⾯语句,可以得到 SQL SERVER ⽀持的所有排序规则。
select * from ::fn_helpcollations()
排序规则名称由两部份构成,前半部份是指本排序规则所⽀持的字符集。
如:
Chinese_PRC_CS_AI_WS
前半部份:指 UNICODE 字符集, Chinese_PRC_ 指针对⼤陆简体字 UNICODE 的排序规则。 排序规则的后半部份即后缀 含义:
_BIN ⼆进制排序
_CI(CS) 是否区分⼤⼩写, CI 不区分, CS 区分
_AI(AS) 是否区分重⾳, AI 不区分, AS 区分
_KI(KS) 是否区分假名类型 ,KI 不区分, KS 区分
_WI(WS) 是否区分宽度 WI 不区分, WS 区分
区分⼤⼩写 : 如果想让⽐较将⼤写字母和⼩写字母视为不等,请选择该选项。
卡片制作区分重⾳ : 如果想让⽐较将重⾳和⾮重⾳字母视为不等,请选择该选项。如果选择该选项, ⽐较还将重⾳不同的字母视为不等。
区分假名 : 如果想让⽐较将⽚假名和平假名⽇语⾳节视为不等,请选择该选项。
区分宽度 : 如果想让⽐较将半⾓字符和全⾓字符视为不等,请选择该选项
利⽤排序规则特点计算汉字笔划和取得拼⾳⾸字母
SQL SERVER的排序规则平时使⽤不是很多,也许不少初学者还⽐较陌⽣,但有
⼀个错误⼤家应是经常碰到: SQL SERVER数据库,在跨库多表连接查询时,若两数据
库默认字符集不同,系统就会返回这样的错误:
“⽆法解决 equal to 操作的排序规则冲突。”
⼀.错误分析:
这个错误是因为排序规则不⼀致造成的,我们做个测试,⽐如:
create table #t1(
name varchar(20) collate Albanian_CI_AI_WS,
value int)
create table #t2(
意大利首都在哪name varchar(20) collate Chinese_PRC_CI_AI_WS,
value int )
表建好后,执⾏连接查询:
select * from #t1 A inner join #t2 B on A.name=B.name
这样,错误就出现了:
服务器: 消息 446,级别 16,状态 9,⾏ 1
⽆法解决 equal to 操作的排序规则冲突。
要排除这个错误,最简单⽅法是,表连接时指定它的排序规则,这样错误就
不再出现了。语句这样写:
select *
from #t1 A inner join #t2 B
on A.name=B.name collate Chinese_PRC_CI_AI_WS
⼆.排序规则简介:
什么叫排序规则呢?MS是这样描述的:"在 Microsoft SQL Server 2000 中,
字符串的物理存储由排序规则控制。排序规则指定表⽰每个字符的位模式以及存
储和⽐较字符所使⽤的规则。"
在查询分析器内执⾏下⾯语句,可以得到SQL SERVER⽀持的所有排序规则。
select * from ::fn_helpcollations()
排序规则名称由两部份构成,前半部份是指本排序规则所⽀持的字符集。
如:
Chinese_PRC_CS_AI_WS
前半部份:指UNICODE字符集,Chinese_PRC_指针对⼤陆简体字UNICODE的排序规则。
排序规则的后半部份即后缀 含义:
_BIN ⼆进制排序
_CI(CS) 是否区分⼤⼩写,CI不区分,CS区分
_AI(AS) 是否区分重⾳,AI不区分,AS区分
_KI(KS) 是否区分假名类型,KI不区分,KS区分
_WI(WS) 是否区分宽度 WI不区分,WS区分
区分⼤⼩写:如果想让⽐较将⼤写字母和⼩写字母视为不等,请选择该选项。
区分重⾳:如果想让⽐较将重⾳和⾮重⾳字母视为不等,请选择该选项。如果选择该选项,
⽐较还将重⾳不同的字母视为不等。
区分假名:如果想让⽐较将⽚假名和平假名⽇语⾳节视为不等,请选择该选项。
区分宽度:如果想让⽐较将半⾓字符和全⾓字符视为不等,请选择该选项
三.排序规则的应⽤:
SQL SERVER提供了⼤量的WINDOWS和SQLSERVER专⽤的排序规则,但它的应⽤往往被开发⼈员所忽略。其实它在实践中⼤有⽤处。
例1:让表NAME列的内容按拼⾳排序:
create table #t(id int,name varchar(20))
insert #t select 1,'中'
union all select 2,'国'
union all select 3,'⼈'
union all select 4,'阿'
select * from #t order by name collate Chinese_PRC_CS_AS_KS_WS
drop table #t
/*结果:
五月你好id name
----------- --------------------
4 阿
2 国
3 ⼈
1 中
*/
例2:让表NAME列的内容按姓⽒笔划排序:
create table #t(id int,name varchar(20))
手机打不出去电话什么原因insert #t select 1,'三'
union all select 2,'⼄'
union all select 3,'⼆'
union all select 4,'⼀'民族特节日
union all select 5,'⼗'
select * from #t order by name collate Chinese_PRC_Stroke_CS_AS_KS_WS
drop table #t
/
*结果:
id name
----------- --------------------
4 ⼀
2 ⼄
3 ⼆
5 ⼗
1 三
*/
四.在实践中排序规则应⽤的扩展
SQL SERVER汉字排序规则可以按拼⾳、笔划等排序,那么我们如何利⽤这种功能
来处理汉字的⼀些难题呢?我现在举个例⼦:
⽤排序规则的特性计算汉字笔划
要计算汉字笔划,我们得先做准备⼯作,我们知道,WINDOWS多国汉字,UNICODE⽬前收录汉字共20902个。简体GBK码汉字UNICODE值从19968开始。
⾸先,我们先⽤SQLSERVER⽅法得到所有汉字,不⽤字典,我们简单利⽤SQL语句就
可以得到:
select top 20902 code=identity(int,19968,1) into #t from syscolumns a,syscolumns b 再⽤以下语句,我们就得到所有汉字,它是按UNICODE值排序的:
select code,nchar(code) as CNWord from #t
然后,我们⽤SELECT语句,让它按笔划排序。
select code,nchar(code) as CNWord
from #t
order by nchar(code) collate Chinese_PRC_Stroke_CS_AS_KS_WS,code
结果:
code CNWord
----------- ------
19968 ⼀
20008 ⼁
20022 ⼂
20031 ⼃
20032 乀
20033 乁
20057 ⼄
20058 乚
20059 乛
20101 ⼅
19969 丁
..........
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论