3

RTRIM(expression, characters)次のクエリを使用して、MsSql Server2008R2でOracleをエミュレートしようとしています。

REVERSE(
        SUBSTRING(
                  REVERSE(field),
                  PATINDEX('%[^chars]%', REVERSE(field)),
                  LEN(field) - PATINDEX('%[^chars]%', REVERSE(field)) + 1
             )
       )

問題は、エスケープが必要なような文字をトリミングできるよう]にしたいということです。^

これを行う方法がわかりません。\]動作しないようなもの。

私はこのESCAPE句を知っていますが、それがどのように機能するかを正確に理解していません。ちなみに、SqlServerは、パターン文字列の直後に配置すると、句を拒否します。

楽しい事実:

私が書いた場合%[^^]%(トリミングしたい^)、それは機能しません。

私が書く%[^ ^]%とそれはトリムします^が、明らかにスペースもトリムします!

4

2 に答える 2

1

きれいではありませんが...

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

使用法

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
于 2013-03-08T11:03:31.570 に答える
1

このドキュメントはMSConnectで見つかりました:http:
//connect.microsoft.com/SQLServer/feedback/details/259534/patindex-missing-escape-clause

ESCAPEユーザーがで句について質問するとPATINDEX、別のユーザーもその要求を拡張しCHARINDEXます。

MSの回答:修正されないため、チケットはクローズされました:(

私は自分のカスタム関数を書き終えました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

そしてのためにRTrim

CREATE FUNCTION RTrim_Chars (
  @BaseString varchar(2000),
  @TrimChars varchar(100)
)

RETURNS varchar(2000) AS

BEGIN

  RETURN REVERSE(LTrim_Chars(REVERSE(@BaseString), @TrimChars))

END

少なくとも、私はいくつかのMsSqlスクリプトを学びました...


編集:

NULLOracleとPostgresの動作を反映するために、2つの引数のチェックを追加しました。

残念ながら、Oracleの動作はまだ少し異なります。長さ0の文字列はOracleの場合と同様であるため、
を記述した場合はLTRIM(string, '')、が返されます。実際には、の結果が返されます。NULLNULLLTRIM(string, NULL)NULL

ところで、これは本当に奇妙なケースです。

于 2013-03-08T12:03:13.243 に答える