指定“COLLATE Latin1_General_CS_AS”,查询结果仍然“不区分大小写”

时间:2016-11-01 23:25:31

标签: sql sql-server tsql

我只想从一个表中选择员工的姓氏用小写字母表示的行。但是,当我运行下面的查询时

SELECT empid, lastname
 FROM HR.Employees
 WHERE lastname COLLATE Latin1_General_CS_AS LIKE '[a-z]%';

它返回员工姓氏以小写字母或大写字母开头的所有行。

我已经指定查询应该与COLLATE Latin1_General_CS_AS区分大小写,为什么不过滤掉以大写字母开头的姓氏?

3 个答案:

答案 0 :(得分:5)

根据SQL Server Books Online,范围搜索中包含的字符取决于排序规则的排序规则。排序规则Latin1_General_CS_AS使用字典顺序,因此包含指定范围的大写和小写字符。

指定二进制排序规则以获取所需的行为(97-122代码点范围内的26个ASCII字符):

SELECT empid, lastname
FROM HR.Employees
WHERE lastname COLLATE Latin1_General_BIN LIKE '[a-z]%';

请注意,显式排序规则会导致非sargable表达式,因此即使lastname上存在索引,也需要进行完整的表/索引扫描。虽然它可能在这里没有帮助,因为大多数(如果不是全部)姓氏以字母开头,通常可以为不区分大小写的超集添加一个sargable表达式以便于索引搜索。如果使用索引,则匹配搜索谓词的行将通过区分大小写的谓词进行额外过滤。

SELECT empid, lastname
FROM HR.Employees
WHERE lastname COLLATE Latin1_General_BIN LIKE '[a-z]%'
    AND lastname LIKE '[a-z]%';

答案 1 :(得分:3)

[a-c]将包含a,A,b,B,c,所以在这个范围内给出你想要的每个字母,就像波纹管一样。

private void storeMessage(String msg){
    File centralFile = new File("path to your file");
    BufferedWriter writer = new BufferedWriter(new FileWriter(centralFile));
    writer.write(msg);
    writer.close();
}

答案 2 :(得分:1)

另一种方法可能是查看第一个字符的ASCII码:

DECLARE @tbl TABLE(Name VARCHAR(100));
INSERT INTO @tbl VALUES('Adam'),('adam')
                      ,('John'),('john')
                      ,('Jane'),('jane')
                      ,('Zaccharias'),('zaccharias');
SELECT * 
FROM @tbl
WHERE ASCII(LEFT(Name,1)) BETWEEN ASCII('a') AND ASCII('z')