我的字段值大小寫混合。 我想只返回大寫字母的值作爲一個結果,同樣在另一個返回小寫字母的值。我不想將一個轉換爲另一個,只是按照原樣返回當前數據。SQL返回列中的所有大寫字母值
我似乎無法找到一份聲明中做到這一點,「串」將只返回我指定,即第一個和最後一個字符
價值因此,舉例來說,如果我有AABBCCDD並希望返回大寫值,我需要的結果是AACC。
我的字段值大小寫混合。 我想只返回大寫字母的值作爲一個結果,同樣在另一個返回小寫字母的值。我不想將一個轉換爲另一個,只是按照原樣返回當前數據。SQL返回列中的所有大寫字母值
我似乎無法找到一份聲明中做到這一點,「串」將只返回我指定,即第一個和最後一個字符
價值因此,舉例來說,如果我有AABBCCDD並希望返回大寫值,我需要的結果是AACC。
與函數:
CREATE FUNCTION [dbo].[GetCased](@BUFFER VARCHAR(MAX), @GETUPPER BIT) RETURNS VARCHAR(MAX) AS
BEGIN
DECLARE @LEN INT = LEN(@BUFFER), @POS INT = 1, @CHAR CHAR(1), @RESULT VARCHAR(MAX) = ''
WHILE @POS <= @LEN BEGIN
SET @CHAR = SUBSTRING(@BUFFER, @POS, 1)
SET @RESULT += CASE WHEN @CHAR COLLATE Latin1_General_CS_AS =
CASE WHEN @GETUPPER = 1 THEN UPPER(@CHAR) ELSE LOWER(@CHAR) END COLLATE Latin1_General_CS_AS THEN @CHAR ELSE '' END
SET @POS += 1
END
RETURN @RESULT
END
...
select
dbo.GetCased('AAbbCCdd', 1) as 'all upper',
dbo.GetCased('AAbbCCdd', 0) as 'all lower'
或者
CREATE FUNCTION [dbo].[fnRemovePatternFromString](@BUFFER VARCHAR(MAX), @PATTERN VARCHAR(128)) RETURNS VARCHAR(MAX) AS
BEGIN
DECLARE @POS INT = PATINDEX(@PATTERN, @BUFFER COLLATE Latin1_General_CS_AS)
WHILE @POS > 0 BEGIN
SET @BUFFER = STUFF(@BUFFER, @POS, 1, '')
SET @POS = PATINDEX(@PATTERN, @BUFFER COLLATE Latin1_General_CS_AS)
END
RETURN @BUFFER
END
...
select
dbo.fnRemovePatternFromString('AAbbCCdd ', '%[ABCDEFGHIJKLMNOPQRSTUVWXYZ]%') as 'all lower'
dbo.fnRemovePatternFromString('AAbbCCdd ', '%[abcdefghijklmnopqrstuvwxyz]%') as 'all upper'
(不能使用[AZ])
下面是使用功能的另一種方式:
CREATE FUNCTION [dbo].returnUppers
(
@str AS varchar(Max)
)
RETURNS varchar(MAX)
AS
BEGIN
DECLARE @len INT
DECLARE @cc INT = 1
DECLARE @return VARCHAR(MAX) = ''
SELECT @len = LEN(@str)
WHILE @len >= @cc
BEGIN
IF UPPER(SUBSTRING(@str,@cc,1)) = SUBSTRING(@str,@cc,1) COLLATE sql_latin1_general_cp1_cs_as
SELECT @return = @return + SUBSTRING(@str,@cc,1)
SET @cc += 1
END
RETURN @return
END
GO
要使用:
DECLARE @string VARCHAR(20) = 'AAbbCCdd'
SELECT dbo.returnUppers(@string)
返回AACC。您需要編寫一個類似的函數,只需將UPPER()更改爲LOWER()
正如在註釋中提到的 - 這應該在表示層中完成,而不是在SQL中完成。
但是,這並不能阻止它有點兒樂趣!
關鍵是使用區分大小寫的排序規則。在這個例子中,我走了SQL_Latin1_General_CP1_ CS _As(以下簡稱「CS」 =區分大小寫。「CI」 = CASEINSENSITIVE)
你永遠不會有這種事情即可獲得良好性能,雖然作爲解決方案涉及循環(在這種情況下遞歸的CTE)
DECLARE @t table (
a char(10)
);
INSERT INTO @t (a)
VALUES ('AbC')
, ('ABCDEFGHIJ')
, ('aBCdEFghij')
, ('AbcdefhhiJ')
, ('ABcdEFGhij')
;
--SELECT a
-- , a COLLATE SQL_Latin1_General_CP1_CS_AS As case_sensitive_collation
-- , Replace(a COLLATE SQL_Latin1_General_CP1_CS_AS, 'A', '#') As case_sensitive_replace
--FROM @t
--;
; WITH characters_to_replace AS (
SELECT number
, Char(number) As c
, Row_Number() OVER (ORDER BY number) As sequence
FROM dbo.numbers
WHERE number BETWEEN 1 AND 255 -- basic characters
AND number NOT BETWEEN 65 AND 90 -- Exclude capital A-Z
)
, replacements AS (
SELECT a As original_value
, Cast(a COLLATE SQL_Latin1_General_CP1_CS_AS As nvarchar(max)) As new_value
, Cast(0 As bigint) As sequence
FROM @t
UNION ALL
SELECT replacements.original_value
, Cast(Replace(replacements.new_value, characters_to_replace.c, '') As nvarchar(max))
, characters_to_replace.sequence
FROM replacements
INNER
JOIN characters_to_replace
ON characters_to_replace.sequence = replacements.sequence + 1
)
SELECT original_value
, new_value
FROM replacements
WHERE sequence = (SELECT Max(sequence) FROM characters_to_replace)
OPTION (MaxRecursion 255)
;
在SQL中沒有簡單的方法來做到這一點 - 在前端語言中有很簡單的方法。你確定你需要在服務器端做到這一點嗎? – Hogan
我不明白你的問題。你想從單個列中提取大寫字母嗎?或者你想要返回列中所有字母都是大寫的值? –
@GordonLinoff他想提取 – Hogan