Недопустимый параметр длины, переданный функции RIGHT в операторе обновления
Кто-нибудь знает, почему мое обновление не работает, если я пытаюсь установить два столбца одновременно?
UPDATE mytable
SET [Customer] = RIGHT([Customer], CHARINDEX('#', REVERSE([Customer])) -1) ,
[Segment] = RIGHT([Segment], CHARINDEX('#', REVERSE([Segment])) -1)
WHERE CHARINDEX('#', [Customer]) > 0 OR
CHARINDEX('#', [Segment]) > 0
Если я выполню запрос с обновлением только одного столбца, он будет работать так, как ожидается. Если я бегу с обоими, я получаю следующую ошибку:
Invalid length parameter passed to the RIGHT function. The statement has been terminated.
Я знаю, что это может произойти, когда CHARINDEX возвращает 0, но я пытаюсь контролировать это с помощью предложения WHERE.
4 ответа
У вас есть OR
в WHERE
пункт. Если вы действительно хотите контролировать его, замените его на AND
:
UPDATE mytable
SET [Customer] = RIGHT([Customer], CHARINDEX('#', REVERSE([Customer])) -1) ,
[Segment] = RIGHT([Segment], CHARINDEX('#', REVERSE([Segment])) -1)
WHERE CHARINDEX('#', [Customer]) > 0 AND
CHARINDEX('#', [Segment]) > 0
В качестве альтернативы:
UPDATE mytable
SET [Customer] = (CASE WHEN Customer LIKE '%#%'
THEN RIGHT([Customer], CHARINDEX('#', REVERSE([Customer])) -1)
ELSE Customer
END)
[Segment] = (CASE WHEN Segment LIKE '%#%'
THEN RIGHT([Segment], CHARINDEX('#', REVERSE([Segment])) -1)
ELSE Segment
END)
WHERE Customer LIKE '%#%' OR Segment LIKE '%#%';
Может быть что-то вроде:
UPDATE mytable SET
[Customer] = Case When CHARINDEX('#', [Customer]) > 0 Then RIGHT([Customer], CHARINDEX('#', REVERSE([Customer])) -1) Else [Customer] End ,
[Segment] = Case When CHARINDEX('#', [Segment]) > 0 Then RIGHT([Segment], CHARINDEX('#', REVERSE([Segment])) -1) Else [Segment] End
WHERE
CHARINDEX('#', [Customer]) > 0 OR
CHARINDEX('#', [Segment]) > 0
Если вы хотите обновить оба, и иногда один или другой будет иметь "#", то вы можете использовать:
UPDATE MyTable
SET
Customer = CASE
WHEN CHARINDEX('#', Customer) > 0 THEN RIGHT(Customer, CHARINDEX('#', REVERSE(Customer)) -1)
ELSE Customer
END,
Segment = CASE
WHEN CHARINDEX('#', Segment) > 0 THEN RIGHT(Segment, CHARINDEX('#', REVERSE(Segment)) -1)
ELSE Segment
END
WHERE
CHARINDEX('#', Customer) > 0 OR
CHARINDEX('#', Segment) > 0
Конечно, в качестве альтернативы вы можете разбить его на две части UPDATE
заявления, но я думаю, что этот будет работать быстрее, так как он должен будет сделать только один проход через таблицу.
Причиной вашего сообщения об ошибке является отрицательное значение, передаваемое RIGHT
функция. От BOL:
integer_expression Положительное целое число, которое указывает, сколько символов character_expression будет возвращено. Если integer_expression является отрицательным, возвращается ошибка.
Ваш WHERE
условие содержит OR
, что позволит включать строки без "#", если в столбце "другой" они есть.
Попробуйте изменить ваш OR
для AND
:
UPDATE mytable
SET [Customer] = RIGHT([Customer], CHARINDEX('#', REVERSE([Customer])) -1) ,
[Segment] = RIGHT([Segment], CHARINDEX('#', REVERSE([Segment])) -1)
WHERE CHARINDEX('#', [Customer]) > 0 AND
CHARINDEX('#', [Segment]) > 0