我试图效仿Oracle的RTRIM(expression, characters)
在MSSQL Server 2008 R2中使用以下查询:
REVERSE(
SUBSTRING(
REVERSE(field),
PATINDEX('%[^chars]%', REVERSE(field)),
LEN(field) - PATINDEX('%[^chars]%', REVERSE(field)) + 1
)
)
问题是,我希望能够像修剪字符]
和^
里面做可能需要转义。
我不知道如何做到这一点。 喜欢的东西\]
不起作用。
我知道的ESCAPE
子句,但我不明白它是如何工作的,并顺便说一下,SqlServer的拒绝它,如果模式串后摆正。
有趣的事实:
如果我写%[^^]%
渴望修剪^
),这是行不通的。
如果我写%[^ ^]%
它修剪^
,但显然也修剪空间!
不漂亮,但...
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
我发现MS连接此文件:
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脚本...
编辑:
我加了NULL
检查两个参数,以反映Oracle和Postgres的行为。
不幸的是,甲骨文仍然表现略有不同:
在情况下,你写LTRIM(string, '')
它返回NULL
,因为0长度的字符串就像是NULL
在Oracle中,所以它实际上返回的结果LTRIM(string, NULL)
这是NULL
确实如此。
顺便说一句,这是一个非常奇怪的情况。
文章来源: Escaping ] and ^ characters in a T-SQL “pattern” expression character class