SQL仅删除前导或尾随回车

时间:2015-06-24 19:57:59

标签: sql sql-server string tsql

我傻眼了,这个问题已经没有被有意义地提出过了。如何在LTRIMRTRIM等SQL中创建等效函数,以便仅在字符串的开头或结尾处进行回车和换行。

显然REPLACE(REPLACE(@MyString,char(10),''),char(13),'')会删除所有回车符和新换行符。这不是我想要的。我只想删除前导或尾随。

5 个答案:

答案 0 :(得分:26)

找到 CHAR(13)CHAR(10)的第一个字符,并从字符串的长度中减去其位置。

<强> LTRIM()

SELECT RIGHT(@MyString,LEN(@MyString)-PATINDEX('%[^'+CHAR(13)+CHAR(10)+']%',@MyString)+1)

<强> RTRIM()

SELECT LEFT(@MyString,LEN(@MyString)-PATINDEX('%[^'+CHAR(13)+CHAR(10)+']%',REVERSE(@MyString))+1)

答案 1 :(得分:9)

以下函数是您可以使用的trim函数的增强类型。复制自sqlauthority.com

这些函数删除尾随空格,前导空格,空格,制表符,回车符,换行符等。

向左修剪

CREATE FUNCTION dbo.LTrimX(@str VARCHAR(MAX)) RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE @trimchars VARCHAR(10)
SET @trimchars = CHAR(9)+CHAR(10)+CHAR(13)+CHAR(32)
IF @str LIKE '[' + @trimchars + ']%' SET @str = SUBSTRING(@str, PATINDEX('%[^' + @trimchars + ']%', @str), 8000)
RETURN @str
END

修剪正确

CREATE FUNCTION dbo.RTrimX(@str VARCHAR(MAX)) RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE @trimchars VARCHAR(10)
SET @trimchars = CHAR(9)+CHAR(10)+CHAR(13)+CHAR(32)
IF @str LIKE '%[' + @trimchars + ']'
SET @str = REVERSE(dbo.LTrimX(REVERSE(@str)))
RETURN @str
END

修剪左右

CREATE FUNCTION dbo.TrimX(@str VARCHAR(MAX)) RETURNS VARCHAR(MAX)
AS
BEGIN
RETURN dbo.LTrimX(dbo.RTrimX(@str))
END

使用功能

SELECT dbo.TRIMX(@MyString)

答案 2 :(得分:3)

以下是您可以运行的示例:

我决定将结果转换为Xml值,因此当您点击它时,您将能够查看回车。

DECLARE @CRLF Char(2) = (CHAR(0x0D) + CHAR(0x0A))
DECLARE @String VarChar(MAX) = @CRLF + @CRLF + '    Hello' + @CRLF + 'World  ' + @CRLF + @CRLF
--Unmodified String:
SELECT CAST(@String as Xml)[Unmodified]
--Remove Trailing Whitespace (including Spaces).
SELECT CAST(LEFT(@String, LEN(REPLACE(@String, @CRLF, '  '))) as Xml)[RemoveTrailingWhitespace]
--Remove Leading Whitespace (including Spaces).
SELECT CAST(RIGHT(@String, LEN(REVERSE(REPLACE(@String, @CRLF, '  ')))) as Xml)[RemoveLeadingWhitespace]
--Remove Leading & Trailing Whitespace (including Spaces).
SELECT CAST(SUBSTRING(@String, LEN(REPLACE(@String, ' ', '_')) - LEN(REVERSE(REPLACE(@String, @CRLF, '  '))) + 1, LEN(LTRIM(RTRIM(REPLACE(@String, @CRLF, '  '))))) as Xml)[RemoveAllWhitespace]
--Remove Only Leading and Trailing CR/LF's (while still preserving all other Whitespace - including Spaces). - 04/06/2016 - MCR.
SELECT CAST(SUBSTRING(@String, PATINDEX('%[^'+CHAR(13)+CHAR(10)+']%',@String), LEN(REPLACE(@String, ' ', '_')) - PATINDEX('%[^'+CHAR(13)+CHAR(10)+']%',@String) + 1 - PATINDEX('%[^'+CHAR(13)+CHAR(10)+']%', REVERSE(@String)) + 1) as Xml)[RemoveLeadingAndTrailingCRLFsOnly]

请记住删除Cast-to-Xml,因为这只是作为一个概念验证来显示它的工作原理。

这比当前接受的答案更好?

乍一看,这似乎比使用的接受答案使用更多功能 但事实并非如此 如果您结合接受的答案中列出的两种方法(删除两者尾随和前导空格),您将需要进行两次更新记录,复制全部一个逻辑到另一个(列出了所有@String),这将导致更多的函数调用,并且变得更难以阅读。

答案 3 :(得分:0)

在SQL Server 2017中,您可以使用TRIM功能一次性删除开头和结尾的特定字符:

WITH testdata(str) AS (
    SELECT CHAR(13) + CHAR(10) + ' test ' + CHAR(13) + CHAR(10)
)
SELECT
    str,
    TRIM(CHAR(13) + CHAR(10) + CHAR(9) + ' ' FROM str) AS [trim cr/lf/tab/space],
    TRIM(CHAR(13) + CHAR(10) FROM str) AS [trim cr/lf],
    TRIM(' ' FROM str) AS [trim space]
FROM testdata

结果:

+----------------+---------------------+------------+----------------+
|str             |trim cr/lf/tab/space |trim cr/lf  |trim space      |
+----------------+---------------------+------------+----------------+
|␍␊␠test␠␍␊ |test                 |␠test␠    |␍␊␠test␠␍␊ |
+----------------+---------------------+------------+----------------+

请注意,最后一个示例(修剪空间)没有按预期执行任何操作。

答案 4 :(得分:0)

我被困在Microsoft SQL Server 2008 R2上,因此将函数基于@sqluser的answer提出了以下内容。如果该字符串仅包含要修剪的字符,则将返回一个空字符串。

让我吃惊的是PATINDEX的模式必须包含在%个字符之间,有一段时间我一直认为它与LIKE语句中的通配符相同,但我现在认为是只是表示模式的语法,尽管我可能是错的!

CREATE FUNCTION [dbo].[ExtendedLTRIM](@string_to_trim VARCHAR(MAX)) 
    RETURNS VARCHAR(MAX)
AS
BEGIN
    DECLARE @tab CHAR(1) = CHAR(9);
    DECLARE @line_feed CHAR(1) = CHAR(10);
    DECLARE @carriage_return CHAR(1) = CHAR(13);
    DECLARE @space CHAR(1) = CHAR(32);

    DECLARE @characters_to_trim VARCHAR(10)
    SET @characters_to_trim = @tab + @line_feed + @carriage_return + @space

    IF @string_to_trim LIKE '[' + @characters_to_trim + ']%'
    BEGIN
        DECLARE @first_non_trim_character INT = PATINDEX('%[^' + @characters_to_trim + ']%', @string_to_trim);

        IF @first_non_trim_character = 0 RETURN '';

        RETURN SUBSTRING(@string_to_trim, @first_non_trim_character, 8000)
    END

    RETURN @string_to_trim
END
GO