代码之家  ›  专栏  ›  技术社区  ›  Stephanie

子字符串中的CHARINDEX减法无效

  •  -2
  • Stephanie  · 技术社区  · 7 年前

    我需要在列名中分解一个值: 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得到子字符串中的最后一个值时,就会发生这种情况。 代码:

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

    'ABC-ABC: ABCDEFG-ABCDEF GH' . 这会给出负值,因此会出现错误。结果应该是 ABCDEFG

    5 回复  |  直到 7 年前
        1
  •  2
  •   John Cappelletti    7 年前

    另一个选项是使用 NullIf()

    实例

    ... 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
    
        2
  •  1
  •   Gordon Linoff    7 年前

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

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

    我不是100%确定这是否符合您的要求,但它将修复您遇到的错误。

        3
  •  1
  •   Community Mohan Dere    6 年前

    你可以走另一条路:

    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;
    
        4
  •  0
  •   Tab Alleman    7 年前

    DECLARE @Name varchar(31) = 'AB: ABC-ABCDE';
    
    SELECT SUBSTRING(@Name, CHARINDEX(' ',@Name)+1,CHARINDEX('-',@Name)-(CHARINDEX(' ',@Name)+1))
    

    ABC .

        5
  •  0
  •   forpas    7 年前

    有时,有些空间是你不希望的。
    因此,从 ":" "-" 并修剪它:

    RTRIM(LTRIM(SUBSTRING(Name, CHARINDEX(':',Name)+1,CHARINDEX('-',Name)-(CHARINDEX(':',Name)+1))))
    
    推荐文章