Подтвердить что ты не робот

Неверный параметр длины передается функции LEFT или SUBSTRING

У меня есть следующее описание: "Образец продукта Product Product Product XYZ - Size", и я хотел бы получить только значение "Product XYZ". Если бы это была только одна строка, у меня не было бы проблемы с использованием SUBSTRING, но у меня есть тысячи записей, и хотя начальное значение Sample Product Maker одинаково для всех продуктов, имя продукта может отличаться, и я не хочу ничего после дефис.

То, что я до сих пор порождало ошибку в заголовке этого вопроса.

SELECT i.Itemid,
       RTRIM(LTRIM(SUBSTRING(i.ShortDescription, 25, (SUBSTRING(i.ShortDescription, 25, CHARINDEX('-', i.ShortDescription, 25)))))) AS ProductDescriptionAbbrev,
       CHARINDEX('-', i.ShortDescription, 0) - 25  as charindexpos
FROM t_items i

Я получаю "Тип данных аргумента varchar недействителен для аргумента 3 подстрочной функции"

Как вы можете видеть, я получаю значение для последней строки оператора sql, но когда я пытаюсь подключить его к функции SUBSTRING, у меня возникают различные проблемы.

4b9b3361

Ответ 1

Скорее всего, у вас есть строки, где "-" отсутствует, что вызывает вашу ошибку. Попробуйте это...

SELECT i.Itemid,
    SUBSTRING(i.ShortDescription, 22, CHARINDEX('-', i.ShortDescription+'-', 22)) AS ProductDescriptionAbbrev,
FROM t_items i

Ответ 2

Ваш первый вызов SUBSTRING указывает длину SUBSTRING(i.ShortDescription, 25, CHARINDEX('-', i.ShortDescription, 25)).

Вы можете попробовать:

declare @t_items as Table ( ItemId Int Identity, ShortDescription VarChar(100) )
insert into @t_items ( ShortDescription ) values
  ( 'Sample Product Maker Product Name XYZ - Size' )

declare @SkipLength as Int = Len( 'Sample Product Maker' )

select ItemId,
  RTrim( LTrim( Substring( ShortDescription, @SkipLength + 1, CharIndex( '-', ShortDescription, @SkipLength ) - @SkipLength - 1 ) ) ) as ProductDescriptionAbbrev
  from @t_items

Ответ 3

Вы также можете удалить текст Sample Product Maker и перейти оттуда:

SELECT RTRIM(LEFT(
    LTRIM(REPLACE(i.ShortDescription, 'Sample Product Maker', '')),
        CHARINDEX('-', LTRIM(REPLACE(i.ShortDescription, 'Sample Product Maker', 
    '' ))) - 1))
AS ShortDescription

Ответ 4

Проблема заключается в том, что ваш внешний вызов SUBSTRING передается символьным типом данных из внутреннего вызова SUBSTRING в третьем параметре.

                                                  +--This call does not return an integer type
SELECT i.Itemid,                                  V
   RTRIM(LTRIM(SUBSTRING(i.ShortDescription, 25, (SUBSTRING(i.ShortDescription, 25, CHARINDEX('-', i.ShortDescription, 25)))))) AS ProductDescriptionAbbrev,
   CHARINDEX('-', i.ShortDescription, 0) - 25  as charindexpos
FROM t_items i

Третий параметр должен оцениваться до требуемой длины. Возможно, вы имели в виду LEN(SUBSTRING(...))?

Ответ 5

Похоже, вы хотите что-то вроде этого (22, а не 25):

SELECT i.Itemid, 
       RTRIM(LTRIM(SUBSTRING(i.ShortDescription, 22, CHARINDEX('-', i.ShortDescription)-22))) AS ProductDescriptionAbbrev, 
       CHARINDEX('-', i.ShortDescription)-22 as charindexpos
FROM t_items i 

Ответ 6

Вы хотите:

LEFT(i.ShortDescription, isnull(nullif(CHARINDEX('-', i.ShortDescription),0) - 1, 8000))

Обратите внимание, что хорошей практикой является обернуть charindex(...) и patindex(...) с помощью nullif(...,0), а затем обработать нулевой случай, если это необходимо (иногда null - это правильный результат, в этом случае мы хотим весь текст, чтобы мы isnull(...,8000) для требуемой длины).