30

全部,

如何检查指定的 varchar 字符或整个字符串在 T-Sql 中是否为大写?理想情况下,我想编写一个函数来测试字符是否为大写,然后我可以稍后将其应用于通用 varchar。对于非字母字符,它应该返回 false。我只对英文字符感兴趣。

我在 SQL Management Studio 中使用 T-sql,我尝试以这种方式从表中提取以小写字母开头的记录:

select * from TABLE
where SUBSTRING(author,1,1) != LOWER(SUBSTRING(author,1,1))

它返回 0 条记录,但我知道有以大写和小写字母开头的记录。

谢谢


编辑:由于podiluskajoachim-isaksoon都成功地回答了我的问题(这两种方法都适用于我的目的),有人介意解释一下哪种方法是查询具有大量记录的表以过滤掉记录的最有效方法作者是否以大写字母开头?

4

4 回答 4

38

使用排序规则

例如:

if ('a'='A' Collate Latin1_General_CI_AI) 
    print'same 1'
else
    print 'different 1'

if ('a'='A' Collate Latin1_General_CS_AI) 
    print'same 2'
else
    print 'different 2' 

排序规则名称中的 CS 表示区分大小写(和 CI,不区分大小写)。AI/AS 与口音敏感度有关。

或在您的示例中

SUBSTRING(author,1,1) <> LOWER(SUBSTRING(author,1,1)) COLLATE Latin1_General_CS_AI
于 2013-08-08T10:32:17.040 回答
19

检查ch是否为大写,是否为大小写可以转换的字符(即不包括非字母字符);

WHERE UNICODE(ch) <> UNICODE(LOWER(ch))

一个用于测试的 SQLfiddle

于 2013-08-08T10:34:48.757 回答
1

就像是

declare @v varchar(10) = 'ABC', @ret int = 0
select @ret = 1 where upper(@v)=@v COLLATE SQL_Latin1_General_CP1_CS_AS
select @ret
于 2013-08-08T10:33:33.260 回答
1

小写字母与大写字母具有相同的 ASCII 或 UNICODE 值,但小写字母的位标志设置为 32。

这很容易直接检测,或者将检测包装到用户定义的函数中,如 IsUpper() 和 IsLower()。

示例(注意 ASCII() 和 UNICODE() 在这里可以互换使用):

DECLARE @Letter char(1);

SET @Letter = 'A'
PRINT   
    @Letter + space(1) + 
    CASE
    WHEN (UNICODE(@Letter) & 32 > 0) THEN 'is lower case'
    ELSE 'is UPPER CASE'
    END

SET @Letter = 'z'
PRINT   
    @Letter + space(1) + 
    CASE
    WHEN (ASCII(@Letter) & 32 > 0) THEN 'is lower case'
    ELSE 'is UPPER CASE'
    END

-- Output:
--    A is UPPER CASE
--    z is lower case

此函数将使用递归 CTE 查找整个字符串中的任何大写字母:

CREATE FUNCTION [dbo].[ContainsUpper](@InputString [varchar](80))
RETURNS [bit] WITH EXECUTE AS CALLER
AS 
BEGIN
    DECLARE @Result         bit     = 0,
            @LowerString    varchar(80) = lower(@InputString);

    WITH Letters
    AS
    (
        SELECT  Position    = 1,
                IsUpper     = 
                    CASE unicode(left(@InputString,1))
                    WHEN unicode(left(@LowerString,1)) THEN 0
                    ELSE 1
                    END

        UNION ALL

        SELECT  Position    = Position + 1,
                IsUpper     = 
                    CASE unicode(substring(@InputString, Position + 1, 1))
                    WHEN unicode(substring(@LowerString, Position + 1, 1)) THEN 0
                    ELSE 1
                    END
        FROM    Letters
        WHERE   Position < len(@InputString)
    )
    SELECT  @Result = max(convert(int, IsUpper))
    FROM    Letters

    RETURN @Result
END
于 2019-09-15T10:10:51.600 回答