【发布时间】:2021-08-21 09:08:16
【问题描述】:
这个查询怎么可能成功运行:
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 行。
【问题讨论】:
-
ClientIp 字段中是否有任何空值或零长度值?
-
你能创建并发布minimal reproducible example吗?
-
您不能确定 SQL Server 会在处理查询的其他部分之前应用过滤器,具体取决于查询计划。您需要确保 CHARINDEX() -1 不会变成负值。
-
@nire 如果有,它们会被与 SELECT 语句相同的 WHERE 子句忽略。所以我希望这两个语句都有错误,或者根本没有
-
SQL Server 不被强制,也不应该被期望对(非常)相似的查询使用相同的执行计划,@Kevin。事实上,它可以在以后对 same 查询使用不同的查询计划,因为有更好的选择(可能是由于新的索引)。
标签: sql-server tsql sql-update ssms