Escaping ] and ^ characters in a T-SQL “pattern” expression character class

后端 未结 2 691
滥情空心
滥情空心 2021-01-20 19:40

I\'m trying to emulate Oracle\'s RTRIM(expression, characters) in MsSql Server 2008 R2 with the following query:

REVERSE(
        SUBSTRING(
            


        
相关标签:
2条回答
  • 2021-01-20 20:07

    I found this document on MS Connect:
    http://connect.microsoft.com/SQLServer/feedback/details/259534/patindex-missing-escape-clause

    The user asks about ESCAPE clause with PATINDEX, then another user extends the request for CHARINDEX as well.

    MS answer: Ticket closed as Won't fix :(

    I finished writing my own custom function for LTrim:

    CREATE FUNCTION LTrim_Chars (
      @BaseString varchar(2000),
      @TrimChars varchar(100)
    )
    
    RETURNS varchar(2000) AS
    
    BEGIN
    
      DECLARE @TrimCharFound bit
    
      DECLARE @BaseStringPos int
      DECLARE @TrimCharsPos int
    
      DECLARE @BaseStringLen int
      DECLARE @TrimCharsLen int
    
      IF @BaseString IS NULL OR @TrimChars IS NULL
      BEGIN
          RETURN NULL
      END
    
      SET @BaseStringPos = 1
    
      SET @BaseStringLen = LEN(@BaseString)
      SET @TrimCharsLen = LEN(@TrimChars)
    
      WHILE @BaseStringPos <= @BaseStringLen
      BEGIN 
    
          SET @TrimCharFound = 0
          SET @TrimCharsPos = 1
    
          WHILE @TrimCharsPos <= @TrimCharsLen
          BEGIN     
              IF SUBSTRING(@BaseString, @BaseStringPos, 1) = SUBSTRING(@TrimChars, @TrimCharsPos, 1)
              BEGIN
                  SET @TrimCharFound = 1
                  BREAK
              END             
              SET @TrimCharsPos = @TrimCharsPos + 1     
          END
    
          IF @TrimCharFound = 0
          BEGIN
            RETURN SUBSTRING(@BaseString, @BaseStringPos, @BaseStringLen - @BaseStringPos + 1)
          END       
          SET @BaseStringPos = @BaseStringPos + 1
    
      END
    
      RETURN ''
    
    END
    

    And for RTrim:

    CREATE FUNCTION RTrim_Chars (
      @BaseString varchar(2000),
      @TrimChars varchar(100)
    )
    
    RETURNS varchar(2000) AS
    
    BEGIN
    
      RETURN REVERSE(LTrim_Chars(REVERSE(@BaseString), @TrimChars))
    
    END
    

    At least, I learnt some MsSql scripting...


    EDIT:

    I added NULL checks for the two arguments, to reflect Oracle and Postgres' behavior.

    Unfortunately, Oracle still behaves slightly differently:
    in the case you write LTRIM(string, ''), it returns NULL, since a 0-length string is like NULL in Oracle, so it's actually returning the result of LTRIM(string, NULL), which is NULL indeed.

    BTW, this is a really strange case.

    0 讨论(0)
  • 2021-01-20 20:14

    Not pretty, but...

    CREATE FUNCTION dbo.RTRIMCHARS(
        @input AS VARCHAR(MAX), @chars AS VARCHAR(100)
    ) RETURNS VARCHAR(MAX) 
    AS 
    BEGIN
        DECLARE @charpos BIGINT
        DECLARE @strpos BIGINT
    
        SET @strpos = LEN(@input)
        SET @charpos = LEN(@chars)
    
        IF @strpos IS NULL OR @charpos IS NULL RETURN NULL
        IF @strpos = 0 OR @charpos = 0 RETURN @input
    
        WHILE @strpos > 0
        BEGIN
            SET @charpos = LEN(@chars)
            WHILE @charpos > 0
            BEGIN
                IF SUBSTRING(@chars, @charpos, 1) = SUBSTRING(@input, @strpos, 1)
                BEGIN
                    SET @strpos = @strpos - 1
                    BREAK
                END
                ELSE
                BEGIN
                    SET @charpos = @charpos - 1
                END
            END
            IF @charpos = 0 BREAK
        END
        RETURN SUBSTRING(@input, 1, @strpos)
    END
    

    Usage

    SELECT dbo.RTRIMCHARS('bla%123', '123%')   -- 'bla'
    SELECT dbo.RTRIMCHARS('bla%123', '123')    -- 'bla%'
    SELECT dbo.RTRIMCHARS('bla%123', 'xyz')    -- 'bla%123'
    SELECT dbo.RTRIMCHARS('bla%123', ']')      -- 'bla%123'
    SELECT dbo.RTRIMCHARS('bla%123', '')       -- 'bla%123'
    SELECT dbo.RTRIMCHARS('bla%123', NULL)     -- NULL
    SELECT dbo.RTRIMCHARS(NULL, '123')         -- NULL
    
    0 讨论(0)
提交回复
热议问题