Невозможно: оператор UPDATE не выполняется, а SELECT завершается успешно.

Как это возможно, что этот запрос выполняется успешно:

SELECT ClientIp, LEFT(clientip, CHARINDEX(',', clientip) - 1)
FROM tblIISLog
WHERE clientip LIKE '%,%'

но этот оператор обновления вызывает следующую ошибку:

UPDATE tblIISLog
  SET ClientIp = LEFT(clientip, CHARINDEX(',', clientip) - 1)
WHERE clientip LIKE '%,%'
Msg 537, Level 16, State 2, Line 6
Invalid length parameter passed to the LEFT or SUBSTRING function.
The statement has been terminated.

Это точно такая же таблица и предложение where, между которыми не было добавлено никаких строк. Этого не должно происходить, если сервер SQL каким-либо образом не вычисляет LEFT для большего количества строк, чем ожидалось. Кто-нибудь может это объяснить?

РЕДАКТИРОВАТЬ: Обходной путь уже предоставлен ниже, но для ответа на вопрос ПОЧЕМУ. Это план запроса для ОБНОВЛЕНИЯ:

enter image description here

А это для SELECT:

enter image description here

Шаг вычисления скаляра фактически выполняется ДО шага фильтрации, поэтому выражение может проходить по строкам ClientIp без каких-либо символов ','.

Всего 2 ответа


Это не отвечает на вопрос почему один работает, а другой нет, хотя комментарии касаются этого, и это связано с тем, что в плане запроса возможно выражение в SET выводится до WHERE (это может случиться). Возможно, у нас есть чрезмерно упрощенный запрос, и поэтому мы не видим очевидной причины.

Однако, чтобы избежать этого, можно использовать NULLIF:

UPDATE tblIISLog
  SET ClientIp = LEFT(clientip, NULLIF(CHARINDEX(',', clientip),0) - 1)
WHERE clientip LIKE '%,%'

Это будет означать, что выражение будет преобразовано в NULL, если в строке нет ,.


Попробуйте это, чтобы избежать передачи отрицательного значения левой функции:

UPDATE tblIISLog
  SET ClientIp = LEFT(clientip, nullif(CHARINDEX(',', clientip), 0) - 1)
WHERE clientip LIKE '%,%'

Есть идеи?

10000