【问题标题】:SQL Server TRIM characterSQL Server TRIM 字符
【发布时间】:2011-12-11 22:14:15
【问题描述】:

我有以下字符串:'BOB*',如何修剪 * 使其显示为 'BOB'

我尝试了 RTRIM('BOB*','*') 但不起作用,因为说只需要 1 个参数。

【问题讨论】:

  • 老问题的新答案...如果您使用的是 SQL Server 2017,TRIM() function 可能是你们中的一些人的解决方案。
  • 鉴于接受的答案有多具体,我建议将SELECT 'BOB' 作为性能更高的替代方案

标签: sql character trim


【解决方案1】:

这是我过去使用的一个函数。请注意,虽然您可以通过使用额外的参数(例如要删除的字符以及将替换空格字符的内容)使其更通用,但这会大大增加执行时间。在这里,我使用管道在预修剪输入后替换空格。如果需要,将 varchar 更改为 nvarchar。

CREATE FUNCTION [dbo].[TrimColons] 
    (
        @strToTrim varchar(500)
    )
    RETURNS varchar(500)
    AS
    BEGIN
        RETURN REPLACE(REPLACE(LTRIM(RTRIM(REPLACE(REPLACE(LTRIM(RTRIM(@strToTrim)),' ','|'),':',' '))),' ',':'),'|',' ')
    
        /*
        Here's a breakdown of this fancy, schmancy, trimmer
    
        LTRIM(RTRIM(@strToTrim))  trims leading & trailing spaces first
        REPLACE(LTRIM(RTRIM(@strToTrim)),' ','|')  replaces inside spaces with pipe char
        REPLACE(REPLACE(LTRIM(RTRIM(@strToTrim)),' ','|'),':',' ') replaces demarc character, the colon, with spaces
        LTRIM(RTRIM(REPLACE(REPLACE(LTRIM(RTRIM(@strToTrim)),' ','|'),':',' ')))  trims the leading & trailing  converted-to-space demarc char (colon) 
        REPLACE(LTRIM(RTRIM(REPLACE(REPLACE(LTRIM(RTRIM(@strToTrim)),' ','|'),':',' '))),' ',':') replaces the inner space characters back to demar char (colon)
        REPLACE(REPLACE(LTRIM(RTRIM(REPLACE(REPLACE(LTRIM(RTRIM(@strToTrim)),' ','|'),':',' '))),' ',':'),'|',' ') replaces the pipe characters back to original space characters
    
        */
    END

【讨论】:

    【解决方案2】:
        SELECT REPLACE('BOB*', '*', '')  
        SELECT REPLACE('B*OB*', '*', '') 
    -------------------------------------
         Result : BOB
    -------------------------------------
    

    这将替换文本中的所有星号*

    【讨论】:

      【解决方案3】:

      仅当您想删除前导字符和尾随字符时,另一种方法是使用 TRIM 函数。 默认情况下会删除空格,但如果您指定了其他字符,则可以删除其他字符。

      SELECT TRIM('=' FROM '=SPECIALS=') AS Result;

      Result  
      --------
      SPECIALS
      

      很遗憾,LTRIM 和 RTRIM 的工作方式不同,它们只会删除空格,而不是像 TRIM 那样删除指定的字符(如果您指定了它)。

      参考和更多示例: https://database.guide/how-to-remove-leading-and-trailing-characters-in-sql-server/

      【讨论】:

        【解决方案4】:

        @teejay 解决方案很棒。但是下面的代码可以更容易理解:

        declare @X nvarchar(max)='BOB *'
        
        set @X=replace(@X,' ','^')
        
        set @X=replace(@X,'*',' ')
        
        set @X= ltrim(rtrim(@X))
        
        set @X=replace(@X,'^',' ')
        

        【讨论】:

          【解决方案5】:

          SqlServer2017 有一个新的方法:https://docs.microsoft.com/en-us/sql/t-sql/functions/trim-transact-sql?view=sql-server-2017

          SELECT TRIM('0' FROM '00001900'); -> 19

          SELECT TRIM('.,!' FROM '# test .'); -> # 测试

          SELECT TRIM('*' FROM 'BOB*'); --> 鲍勃

          很遗憾,RTRIM 不支持修剪特定字符。

          【讨论】:

            【解决方案6】:

            怎么样..(在这种情况下修剪尾随的逗号或句点)

            对于变量:

            -- Trim commas and full stops from end of City
            WHILE RIGHT(@CITY, 1) IN (',', '.'))    
                SET @CITY = LEFT(@CITY, LEN(@CITY)-1)  
            

            对于表值:

            -- Trim commas and full stops from end of City
            WHILE EXISTS (SELECT 1 FROM [sap_out_address] WHERE RIGHT([CITY], 1) IN (',', '.'))     
                UPDATE [sap_out_address]    
                SET [CITY] = LEFT([CITY], LEN([CITY])-1)  
                WHERE RIGHT([CITY], 1) IN (',', '.') 
            

            【讨论】:

              【解决方案7】:

              一个char参数的解决方案:

              rtrim('0000100','0') -> 选择左('0000100',len(rtrim(replace('0000100','0','')))))

              ltrim('0000100','0') -> 选择权('0000100',len(replace(ltrim(replace('0000100','0','')),'','.'))))

              【讨论】:

                【解决方案8】:

                试试这个:

                原创

                select replace('BOB*','*','')
                

                固定为完全替代

                select replace('BOB*','BOB*','BOB')
                

                【讨论】:

                • 这将替换字符串中的所有 *,而不仅仅是前导和尾随的。
                • 好点。我已经更正了样本。但是我必须指出,传递的字符串是一个文字,所以无论如何它只有一颗星。
                【解决方案9】:

                我对上述一些答案使用了类似的方法,即使用模式匹配并反转字符串以找到第一个不可修剪的字符,然后将其切断。不同的是,这个版本的工作量比上面的少,所以效率应该更高一些。

                • 这将为任何指定字符创建RTRIM 功能。
                • 它包括一个额外的步骤set @charToFind = case... 来转义所选字符。
                • 如果 @charToReplace 是正确的 crotchet (]),目前存在一个问题,因为似乎没有办法逃避这一点。

                .

                declare @stringToSearch nvarchar(max) = '****this is****a  ** demo*****'
                , @charToFind nvarchar(5) = '*' 
                
                --escape @charToFind so it doesn't break our pattern matching
                set @charToFind = case @charToFind 
                    when ']' then '[]]' --*this does not work / can't find any info on escaping right crotchet*
                    when '^' then '\^'
                    --when '%' then '%' --doesn't require escaping in this context
                    --when '[' then '[' --doesn't require escaping in this context
                    --when '_' then '_' --doesn't require escaping in this context
                    else @charToFind
                end
                
                select @stringToSearch
                , left
                (
                    @stringToSearch
                    ,1 
                    + len(@stringToSearch)
                    - patindex('%[^' + @charToFind  + ']%',reverse(@stringToSearch))
                )
                

                【讨论】:

                【解决方案10】:

                修剪多例

                --id = 100 101 102 103 104 105 106 107 108 109 110 111
                select right(id,2)+1  from ordertbl -- 1 2 3 4 5 6 7 8 9 10 11  -- last     two positions are taken
                
                select LEFT('BOB', LEN('BOB')-1) -- BO
                
                select LEFT('BOB*',1) --B
                select LEFT('BOB*',2) --BO
                

                【讨论】:

                  【解决方案11】:
                  CREATE FUNCTION dbo.TrimCharacter
                  (
                      @Value NVARCHAR(4000),
                      @CharacterToTrim NVARCHAR(1)
                  )
                  RETURNS NVARCHAR(4000)
                  AS
                  BEGIN
                      SET @Value = LTRIM(RTRIM(@Value))
                      SET @Value = REVERSE(SUBSTRING(@Value, PATINDEX('%[^'+@CharacterToTrim+']%', @Value), LEN(@Value)))
                      SET @Value = REVERSE(SUBSTRING(@Value, PATINDEX('%[^'+@CharacterToTrim+']%', @Value), LEN(@Value)))
                      RETURN @Value
                  END
                  GO
                  --- Example
                  ----- SELECT dbo.TrimCharacter('***BOB*********', '*')
                  ----- returns 'BOB'
                  

                  【讨论】:

                  • 这个答案需要一些爱
                  【解决方案12】:

                  如果您想删除所有星号,那很明显:

                  SELECT REPLACE('Hello*', '*', '')
                  

                  但是,如果您在末尾有多个星号,并且在整个过程中有多个星号,但只对修剪尾随的星号感兴趣,那么我会使用这个:

                  DECLARE @String VarChar(50) = '**H*i****'
                  SELECT LEFT(@String, LEN(REPLACE(@String, '*', ' ')))              --Returns: **H*i
                  

                  我更新了这个答案,包括展示如何删除前导字符:

                  SELECT RIGHT(@String, LEN(REPLACE(REVERSE(@String), '*', ' ')))    --Returns: H*i****
                  

                  LEN() 有一个“功能”(看起来很像一个错误),它不计算尾随空格。

                  【讨论】:

                  • 这样你会在最后修剪任何空间。此外,您还依赖于一个可能不时被纠正的错误......
                  • @Teejay 出于向后兼容性的原因,现在不可能更改LEN 的行为。忽略尾随空格是记录它的工作方式,因此不会被确认为错误。
                  【解决方案13】:

                  我真的很喜欢Teejay's answer,几乎停在那里。这很聪明,但我有一种“几乎太聪明”的感觉,因为不知何故,你的字符串在某些时候实际上会故意在其中包含~(或其他任何东西)。所以这不足以让我投入生产。

                  我喜欢Chris' too,但PATINDEX 调用似乎有点过头了。

                  虽然可能是micro-optimization,但这里没有PATINDEX:

                  CREATE FUNCTION dbo.TRIMMIT(@stringToTrim NVARCHAR(MAX), @charToTrim NCHAR(1))
                  RETURNS NVARCHAR(MAX)
                  AS
                  BEGIN
                      DECLARE @retVal NVARCHAR(MAX)
                  
                      SET @retVal = @stringToTrim
                  
                      WHILE 1 = charindex(@charToTrim, reverse(@retVal))
                          SET @retVal = SUBSTRING(@retVal,0,LEN(@retVal))
                  
                      WHILE 1 = charindex(@charToTrim, @retVal)
                          SET @retVal = SUBSTRING(@retVal,2,LEN(@retVal))
                  
                      RETURN @retVal
                  END
                  
                  --select dbo.TRIMMIT('\\trim\asdfds\\\', '\')
                  --trim\asdfds
                  

                  返回一个 MAX nvarchar 让我有点不快,但这是最灵活的方法..

                  【讨论】:

                  【解决方案14】:

                  在 MS SQL Server 中实现 Oracle 的 TRIM char FROM string 的另一种很好的方法如下:

                  • 首先,您需要确定一个永远不会在您的字符串中使用的字符,例如~
                  • 您将所有空格替换为该字符
                  • 您将要修剪的字符 * 替换为空格
                  • 你LTrim+RTrim得到的字符串
                  • 您将所有空格替换为修剪后的字符*
                  • 您将所有从未使用过的字符替换为空格

                  例如:

                  REPLACE(REPLACE(LTrim(RTrim(REPLACE(REPLACE(string,' ','~'),'*',' '))),' ','*'),'~',' ')
                  

                  【讨论】:

                  • 这很棒。我修改了这个版本以从字符串中删除前面的 '[' 和 ']',这对于检测它们是否是 db 对象名词(表、sp 等)很有用
                  • 从 SQL Server vNext 你可以使用 TRIM 函数,像这里stackoverflow.com/a/41366032/5070879
                  【解决方案15】:

                  如果您只想在值以 '*' 结尾时从值中删除单个 '*' 字符,那么一个简单的 CASE 表达式将为您完成:

                  SELECT CASE WHEN RIGHT(foo,1) = '*' THEN LEFT(foo,LEN(foo)-1) ELSE foo END AS foo
                    FROM (SELECT 'BOB*' AS foo)
                  

                  要删除所有尾随 '*' 字符,您需要一个更复杂的表达式,使用 REVERSE、PATINDEX、LEN 和 LEFT 函数。

                  注意:小心使用 REPLACE 函数,因为它会替换字符串中指定字符的所有次出现,而不仅仅是尾随的字符。

                  【讨论】:

                    【解决方案16】:

                    如果您想要类似于 RTRIM 处理空格的行为,即“B*O*B**”会变成“B*O*B”而不会丢失嵌入的空格,那么类似 -

                    REVERSE(SUBSTRING(REVERSE('B*O*B**'), PATINDEX('%[^*]%',REVERSE('B*O*B**')), LEN('B*O*B**') - PATINDEX('%[^*]%', REVERSE('B*O*B**')) + 1))
                    

                    应该这样做。

                    【讨论】:

                    • 不幸的是,此方法无法修剪 ] 和 ^(请参阅我在 stackoverflow.com/questions/15290737 的问题)。我在 MsSql 服务器上编写了两个实现 LTRIM 和 RTRIM 的小函数,请在上面链接的同一页面中查看我的自我回答。
                    • 这行得通,但只有正确的修剪值......修剪两侧的最佳方法是什么?
                    【解决方案17】:
                    LEFT('BOB*', LEN('BOB*')-1)
                    

                    应该这样做。

                    【讨论】:

                    • 这将从字符串中删除最后一个字符,无论该字符是否为星号。这适用于以星号结尾的字符串的特殊情况,但不会检查是否应删除最后一个字符。
                    • 它也不会修剪一个以上的星号。
                    • 原始问题没有说“我只想删除一个星号,如果有一个星号”或“我想删除所有星号,不管有多少星号”。我回答了被问到的问题。
                    • 无论字符是特殊字符还是字母或数字,它都会从值中删除最后一个字符,这根本不是通用解决方案。如果您只为'BOB' 做,那么结果将是'BO',根据问题,这不是有效的。
                    • LEFT('BOB*',3)
                    【解决方案18】:

                    RRIM() LTRIM() 只删除空格试试http://msdn.microsoft.com/en-us/library/ms186862.aspx

                    基本上只是用空格替换 *

                    REPLACE('TextWithCharacterToReplace','CharacterToReplace','CharacterToReplaceWith')

                    所以你想要

                    替换('BOB*','*','')

                    【讨论】:

                    • 这将替换字符串中的所有 *,而不仅仅是前导和尾随的。
                    猜你喜欢
                    • 1970-01-01
                    • 2016-09-20
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-01-05
                    • 1970-01-01
                    • 1970-01-01
                    • 2014-02-01
                    • 2014-03-21
                    相关资源
                    最近更新 更多