SQL Server 中大小写区分的处理。
默认情况下,SQL Server 里面是不区分大小写的:
E:>sqlcmd -S "localhostSQLEXPRESS"
1> use test
2> go
已将数据库上下文更改为 'Test'。
-- 建立一个 tab 的测试表, 表名称为全部小写
1> CREATE TABLE [tab] ( id int )
2> go
1> select * from tab
2> go
id
-----------
(0 行受影响)
1> select * from Tab
2> go
id
-----------
(0 行受影响)
上面可以看出,默认情况下,
select * from tab 与 select * from Tab 是一样的。
因为不区分大小写
下面设置 test 数据库,让其区分大小写
alter database test COLLATE Chinese_PRC_CS_AS
1> alter database test COLLATE Chinese_PRC_CS_AS
2> go
1> select * from tab
2> go
id
-----------
(0 行受影响)
1> select * from Tab
2> go
消息 208,级别 16,状态 1,服务器 WANGZHIQINGSQLEXPRESS,第 1 行
对象名 'Tab' 无效。
设置数据库区分大小写以后,可以看到
select * from Tab 的时候, SQL Server 无法识别 "Tab" 这个表了
因为区分大小写了。
下面恢复 test 数据库的设置,让其不区分大小写
alter database test COLLATE Chinese_PRC_CI_AS
1> alter database test COLLATE Chinese_PRC_CI_AS
2> go
1> select * from tab
2> go
id
-----------
(0 行受影响)
1> select * from Tab
2> go
id
-----------
(0 行受影响)
恩,一切又恢复正常了。
上面是 关于 SQL 语句的区分大小写
----------
--分割线--
----------
下面是 关于 数据内容的区分大小写
首先删除前面的测试表
1> drop table [tab]
2> go
重建一个,因为前面的表,只有个 int 字段,没法测大小写。
CREATE TABLE [tab] (
id INT IDENTITY(1,1),
val NVARCHAR(10)
);
go
INSERT INTO [tab]
SELECT 'ABC123' UNION ALL
SELECT 'abc234' UNION ALL
SELECT 'Abc345' UNION ALL
SELECT 'aBC456' UNION ALL
SELECT 'aBc567'
go
1> SELECT
2> *
3> FROM
4> tab
5> WHERE
6> val LIKE 'a%'
7> go
id val
----------- ----------
1 ABC123
2 abc234
3 Abc345
4 aBC456
5 aBc567
(5 行受影响)
从上面的结果,可以看出,默认情况下,对于查询的数据,也是不区分大小写的
LIKE 'a%' 意味着 a 开头 与 A 开头的。
都会被检索出来。
1> SELECT
2> *
3> FROM
4> Tab
5> WHERE
6> val LIKE 'a%' COLLATE Chinese_PRC_CS_AS
7> go
id val
----------- ----------
2 abc234
4 aBC456
5 aBc567
(3 行受影响)
从上面的结果,可以看出,当指定了 COLLATE Chinese_PRC_CS_AS 之后
LIKE 'a%' 将只返回小写字母 a 开头的数据。 大写字母 A 开头的,将不被检索出来。
1> SELECT
2> *
3> FROM
4> Tab
5> WHERE
6> val LIKE 'a%' COLLATE Chinese_PRC_CS_AS
7> AND val LIKE '%B%'
8> go
id val
----------- ----------
2 abc234
4 aBC456
5 aBc567
(3 行受影响)
上面的查询,为检索 小写字母 a 开头的, 中间包含字母 B 或者 b 的 (因为这里的 val LIKE '%B%' 没有区分大小写 )
1>
2> SELECT
3> *
4> FROM
5> Tab
6> WHERE
7> val LIKE 'a%'COLLATE Chinese_PRC_CS_AS
8> AND val LIKE '%B%' COLLATE Chinese_PRC_CS_AS
9> go
id val
----------- ----------
4 aBC456
5 aBc567
(2 行受影响)
上面的查询,为检索 小写字母 a 开头的, 中间包含字母 B 的 (因为这里的 val LIKE '%B%' 区分大小写 )
下面再设置 test 数据库,让其区分大小写
alter database test COLLATE Chinese_PRC_CS_AS
1> alter database test COLLATE Chinese_PRC_CS_AS
2> go
1> SELECT
2> *
3> FROM
4> Tab
5> WHERE
6> val LIKE 'a%'
7> go
消息 208,级别 16,状态 1,服务器 ZQWANG-RDSQLEXPRESS,第 1 行
对象名 'Tab' 无效。
1> SELECT
2> *
3> FROM
4> tab
5> WHERE
6> val LIKE 'a%'
7> go
id val
----------- ----------
1 ABC123
2 abc234
3 Abc345
4 aBC456
5 aBc567
(5 行受影响)
由上面的结果可以看到
alter database test COLLATE Chinese_PRC_CS_AS
这样的语句,只是设置 SQL 语句里面,对 表名/字段名 区分大小写
对查询数据的时候,LIKE 'a%' 的时候, 还是默认不区分大小写的。
下面恢复 test 数据库的设置,让其不区分大小写
alter database test COLLATE Chinese_PRC_CI_AS
1> alter database test COLLATE Chinese_PRC_CI_AS
2> go
每次写SQL, 如果需要区分大小写的话,都加 COLLATE Chinese_PRC_CS_AS 也是一件麻烦的事情。
假如我希望让 Tab 的 val 字段,强制区分大小写的话。
ALTER TABLE tab
ALTER COLUMN val NVARCHAR(10) COLLATE Chinese_PRC_CS_AS
go
1> SELECT
2> *
3> FROM
4> Tab
5> WHERE
6> val LIKE 'a%'
7> go
id val
----------- ----------
2 abc234
4 aBC456
5 aBc567
(3 行受影响)
1> SELECT
2> *
3> FROM
4> Tab
5> WHERE
6> val LIKE 'a%'
7> AND val LIKE '%B%'
8> go
id val
----------- ----------
4 aBC456
5 aBc567
(2 行受影响)
由上面的结果可以看到
执行了
ALTER TABLE tab
ALTER COLUMN val NVARCHAR(10) COLLATE Chinese_PRC_CS_AS
之后。
所有对 tab 表的 val 字段的查询操作。
都自动强制区分大小写了。
恢复 tab 表的 val 字段,不区分大小写
ALTER TABLE tab
ALTER COLUMN val NVARCHAR(10) COLLATE Chinese_PRC_CI_AS
1> ALTER TABLE tab
2> ALTER COLUMN val NVARCHAR(10)(10) COLLATE Chinese_PRC_CI_AS
3> go
1> SELECT
2> *
3> FROM
4> Tab
5> WHERE
6> val LIKE 'a%'
7> go
id val
----------- ----------
1 ABC123
2 abc234
3 Abc345
4 aBC456
5 aBc567
(5 行受影响)
好,一切又恢复到默认情况下了。
----------
--分割线--
----------
处理好了 LIKE 的大小写
现在做做排序。
INSERT INTO [tab]
SELECT '123ABC' UNION ALL
SELECT '234abc' UNION ALL
SELECT '345Abc' UNION ALL
SELECT '456aBC' UNION ALL
SELECT '567aBc'
go
1> SELECT
2> *
3> FROM
4> Tab
5> ORDER BY
6> val
7> go
id val
----------- ----------
6 123ABC
7 234abc
8 345Abc
9 456aBC
10 567aBc
1 ABC123
2 abc234
3 Abc345
4 aBC456
5 aBc567
(10 行受影响)
默认排序,也是不区分大小写的。
在查询 SQL SERVER 支持的排序规则。
SELECT
*
FROM
::fn_helpcollations()
WHERE
name LIKE 'Chinese_PRC%'
1> SELECT
2> *
3> FROM
4> Tab
5> ORDER BY
6> val COLLATE Chinese_PRC_BIN
7> go
id val
----------- ----------
6 123ABC
7 234abc
8 345Abc
9 456aBC
10 567aBc
1 ABC123
3 Abc345
4 aBC456
5 aBc567
2 abc234
(10 行受影响)
注:
ORDER BY val COLLATE Chinese_PRC_CS_AS 好像没有效果。
因此使用 Chinese_PRC_BIN 二进制排序
----------
--分割线--
----------
前面只有英文排序
现在处理中文排序
首先清空数据。
TRUNCATE TABLE Tab
go
INSERT INTO tab
SELECT '一' UNION ALL
SELECT '二' UNION ALL
SELECT '三' UNION ALL
SELECT '四' UNION ALL
SELECT '五'
go
在查询 SQL SERVER 支持的排序规则。
SELECT
*
FROM
::fn_helpcollations()
WHERE
name LIKE 'Chinese_PRC%'
Chinese_PRC_CS_AS_KS_WS:
Chinese-PRC, case-sensitive, accent-sensitive, kanatype-sensitive, width-sensitive
-- 按照拼音来排序
1> SELECT
2> *
3> FROM
4> Tab
5> ORDER BY
6> val COLLATE Chinese_PRC_CS_AS_KS_WS
7> go
id val
----------- ----------
2 二
3 三
4 四
5 五
1 一
(5 行受影响)
Chinese_PRC_Stroke_CI_AS_KS_WS:
Chinese-PRC-Stroke, case-insensitive, accent-sensitive, kanatype-sensitive, width-sensitive
-- 按照笔画数的多少来排序
1> SELECT
2> *
3> FROM
4> Tab
5> ORDER BY
6> val COLLATE Chinese_PRC_Stroke_CS_AS_KS_WS
7> go
id val
----------- ----------
1 一
2 二
3 三
5 五
4 四
(5 行受影响)