SQL Server SUBSTRING中CHARINDEX的减法不起作用

igsr9ssn  于 2022-11-21  发布在  其他
关注(0)|答案(6)|浏览(207)

我有一个值,我需要在列名称中进行分解: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

我做错了什么?
UPDATE:表中有另一个值,如:'ABC-ABC: ABCDEFG-ABCDEF GH'。这会产生负值,因此会产生错误。结果应为ABCDEFG

6fe3ivhb

6fe3ivhb1#

另一个选项是使用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
5m1hhzi4

5m1hhzi42#

你没有空间了。我发现最简单的方法就是加一个:

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

我不能100%肯定这是你想要的,但它会修复你遇到的错误。

hfyxw5xn

hfyxw5xn3#

你可以走另一条路:

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;
b09cbbtk

b09cbbtk4#

您的问题无法重现。

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

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

结果以ABC表示。
您的表中可能有一些数据不符合您声称的格式。

iklwldmw

iklwldmw5#

有时候会有你意想不到的地方。
因此,获取从":""-"的子字符串,并对其进行修剪:

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

n3ipq98p6#

BEGIN
    DECLARE @TEXT AS VARCHAR(20)
    SET @TEXT='E1014654-1'
    SELECT SUBSTRING(@TEXT, CHARINDEX('E', @TEXT)+1, CHARINDEX('-',@TEXT)) as 'STR', 
            CAST(CHARINDEX('E', @Text)+1 AS INT) as 'val1', CAST(CHARINDEX('-', @TEXT) AS INT) as 'val2',  
            (CAST(CHARINDEX('-',@TEXT) AS INT) - CAST(CHARINDEX('E',@TEXT)+1 AS INT)) as 'SUBTR', LEN(@TEXT) as 'LEN'
END

val1和val2中的值当我实际减去它们时,它们给予我一个与运算一致的数值。
如果运行相同的代码但不进行强制转换,则不会产生相同的值:

BEGIN
    DECLARE @TEXT2 AS VARCHAR(20)
    SET @TEXT2='E1014654-1'
    SELECT SUBSTRING(@TEXT2, CHARINDEX('E', @TEXT2)+1, CHARINDEX('-',@TEXT2)) as 'STR', 
            CHARINDEX('E', @TEXT2)+1  as 'val1', CHARINDEX('-', @TEXT2) as 'val2',  
            CHARINDEX('-',@TEXT2)  - CHARINDEX('E',@TEXT2)+1 as 'SUBTR', LEN(@TEXT2) as 'LEN'
END

我宁愿看到SQL有一个INSTRGetStr函数,它将返回一个匹配的字符串,如果不存在,则返回NULL

相关问题