这个查询怎么可能成功运行:
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。 有人能解释一下吗?
编辑: 下面已经提供了一种解决方法,但要回答为什么。这是 UPDATE 的查询计划:
这对于 SELECT :
计算标量步骤实际上是在过滤步骤之前执行的,这就是为什么表达式可以跨越 ClientIp 行而没有任何“,”。
答案 0 :(得分:2)
这并没有回答为什么一个有效而另一个无效的问题,尽管评论涉及它,这是由于在查询计划中可能是 {{1} } 是在 SET
之前派生的(这可能发生)。也许我们上面有一个过于简单的查询,这就是为什么我们看不到明显的原因。
然而,对于避免它,一种方法是使用WHERE
:
NULLIF
这意味着如果字符串中没有 UPDATE tblIISLog
SET ClientIp = LEFT(clientip, NULLIF(CHARINDEX(',', clientip),0) - 1)
WHERE clientip LIKE '%,%';
,表达式将解析为 NULL
。
答案 1 :(得分:1)
试试这个,以避免将负值传递给左函数:
UPDATE tblIISLog
SET ClientIp = LEFT(clientip, nullif(CHARINDEX(',', clientip), 0) - 1)
WHERE clientip LIKE '%,%';