'Invalid length parameter passed to the LEFT or SUBSTRING function' 当 / 不存在时

'Invalid length parameter passed to the LEFT or SUBSTRING function' when / doesn't exist

我有一个存储过程,它应该在 / 字符之后提取所有字符。但是,有时该字段没有字符,那么它应该 return 什么都没有,有时该字段会为空,同样它应该 return 什么也没有。如果 / 字符存在,我所使用的 SQL 会起作用,但如果不存在,我将无法使用,我会在标题中收到错误消息。这是 SQL:

COALESCE(NULLIF(SUBSTRING(s.billing_dept,1,
        CASE WHEN CHARINDEX('/', s.billing_dept) = 0
            THEN 0 
            ELSE (LEN(s.billing_dept)-1) - CHARINDEX('/', s.billing_dept)
        --END,
        --CASE WHEN CHARINDEX('/', s.billing_dept) = 0 
        --  THEN 1 
        --  ELSE ((LEN(s.billing_dept)-1) - CHARINDEX('/', s.billing_dept)) 
        END),''),'') 

如果字符串以 '/'

结尾,这将失败

如果你想要 '/' 之后的所有字符,你应该使用这个:

CASE CHARINDEX('/', s.billing_dept)
WHEN 0 THEN
        ''
ELSE
        SUBSTRING(s.billing_dept, CHARINDEX('/', s.billing_dept) + 1, LEN(s.billing_dept) - CHARINDEX('/', s.billing_dept))
END

你可以试试这个:

CREATE TABLE #teststrings(test nvarchar(20))

INSERT INTO #teststrings(test)
VALUES  (null), (N'Hiho!'), (N'Cool/String'), (N'Cooler / String'), (N'Stupid String /')

SELECT  s.test, 
        SUBSTRING(s.test,1,
            CASE WHEN CHARINDEX(N'/',s.test) = 0 
                THEN LEN(s.test) 
                ELSE CHARINDEX(N'/',s.test)-1 
            END
        ) as string_before,
        SUBSTRING(s.test,CHARINDEX(N'/',s.test)+1,LEN(s.test)) as string_after
FROM #teststrings as s

DROP TABLE #teststrings

我都提供了。一个版本将在 / 之前提供所有内容,称为 string_before,另一个版本将在 / 之后提供所有内容,称为 string_after

此外,我为测试提供了五个不同的测试字符串。

这些是结果:

test                 string_before        string_after
-------------------- -------------------- --------------------
NULL                 NULL                 NULL
Hiho!                Hiho!                Hiho!
Cool/String          Cool                 String
Cooler / String      Cooler                String
Stupid String /      Stupid String        

如果需要和希望,您仍然可以 ltrim/rtrim 结果。此解决方案适用于 SQL Server 2005 直至当前版本。

这是我自己的方法,使用更简单的函数获取 / 之后的字符:

DECLARE @test TABLE (string VARCHAR(10))
INSERT INTO @test (string) VALUES ('/abc'),('a/bc'),('ab/c'),('abc/'),('abc'),(NULL)

SELECT 
    string,
    output = CASE CHARINDEX('/',string)
        WHEN 0 THEN NULL --if / not found, return null
        WHEN LEN(string) THEN NULL --if / is last char, return null
        ELSE RIGHT(string,LEN(string)-CHARINDEX('/',string)) --return all chars after /
        END
FROM @test

string   output
===============
/abc     abc
a/bc     bc
ab/c     c
abc/     NULL
abc      NULL
NULL     NULL