SUBSTRING中的CHARINDEX减法不起作用

时间:2019-01-25 15:35:24

标签: sql sql-server tsql substring charindex

我需要在“名称”列中细分一个值:AB: ABC-ABCDE我需要中间部分为ABC。我正在使用SUBSTRING和CHARINDEX完成此操作,但出现错误:

Msg 537, Level 16, State 2, Line 393
Invalid length parameter passed to the LEFT or SUBSTRING function.

当我减去CHARINDEX以获得SUBSTRING中的最后一个值时,就会发生这种情况。 代码:

SELECT PRODUCT = (SUBSTRING(Name, CHARINDEX(' ',Name)+1,CHARINDEX('-',Name)-(CHARINDEX(' ',Name)+1)))
FROM A

我在做什么错了?

更新:表中还有另一个值,例如:'ABC-ABC: ABCDEFG-ABCDEF GH'。这给出了负值,因此为什么会出错。结果应为ABCDEFG

5 个答案:

答案 0 :(得分:2)

另一种选择是使用NullIf()

“强制” NULL

示例

... NullIf(CHARINDEX(' ',Name),0) + 1 ...

... NullIf(CHARINDEX('-',Name),0) ...

**

  

编辑-请求的更新

**

Declare @YourTable table (Name varchar(50))
Insert Into @YourTable values
( 'AB: ABC-ABCDE')
,('ABC-ABC: ABCDEFG-ABCDEF GH')

Select A.*
      ,ltrim(rtrim(left(substring(Name,charindex(':',Name+':')+1,len(Name))
           ,charindex('-',substring(Name,charindex(':',Name+':')+1,len(Name))+'-') -1
           )))
 From  @YourTable A

返回

Name                          (No column name)
AB: ABC-ABCDE                 ABC
ABC-ABC: ABCDEFG-ABCDEF GH    ABCDEFG

答案 1 :(得分:1)

您没有空间。我发现最简单的方法是只添加一个:

SELECT PRODUCT = (SUBSTRING(Name, CHARINDEX(' ', Name + ' ') + 1, CHARINDEX('-', Name + '-') - (CHARINDEX(' ', Name + ' ') + 1)))
FROM A

我不确定100%会做到这一点,但这会解决您遇到的错误。

答案 2 :(得分:1)

您可能会选择另一条路线:

DECLARE @mockup TABLE(SomeValue VARCHAR(100));
INSERT INTO @mockup VALUES('AB: ABC-ABCDE')
                         ,('CD: blah-blub')
                         ,('Wrong Value here')
                         ,('MissingEnd: isCorrect');

-查询将从XML中选择第二个元素。

SELECT CAST('<x>' + REPlACE(REPLACE(m.SomeValue,'-',' '),' ','</x><x>') + '</x>' AS XML).value('/x[2]','nvarchar(max)')
FROM @mockup m;

诀窍是:使用一些替代方法将您的 AB:ABC-ABCDE 转换为类似XML的

<x>AB:</x>
<x>ABC</x>
<x>ABCDE</x>

从此XML中,我们可以轻松地选择第二个元素。

一个积极的副作用:这种方法可以容忍错误的值...

更新

您的不良价值...新招是使用STUFF()切掉所有内容,直到双点:

DECLARE @mockup TABLE(SomeValue VARCHAR(100));
INSERT INTO @mockup VALUES('AB: ABC-ABCDE')
                         ,('CD: blah-blub')
                         ,('Wrong Value here')
                         ,('MissingEnd: isCorrect')
                         ,('ABC-ABC: ABCDEFG-ABCDEF GH');

SELECT CAST('<x>' + REPlACE(REPLACE(STUFF(m.SomeValue,1,CHARINDEX(':',m.SomeValue),''),'-',' '),' ','</x><x>') + '</x>' AS XML).value('/x[2]','nvarchar(max)')
FROM @mockup m;

答案 3 :(得分:0)

您的问题无法复制。

DECLARE @Name varchar(31) = 'AB: ABC-ABCDE';

SELECT SUBSTRING(@Name, CHARINDEX(' ',@Name)+1,CHARINDEX('-',@Name)-(CHARINDEX(' ',@Name)+1))

结果为ABC

您的表中可能有一些数据不符合您声称的格式。

答案 4 :(得分:0)

有时您可能不希望有空格。
因此,将子串从":""-"进行修剪:

RTRIM(LTRIM(SUBSTRING(Name, CHARINDEX(':',Name)+1,CHARINDEX('-',Name)-(CHARINDEX(':',Name)+1))))