【问题标题】:Impossible: UPDATE statement fails while SELECT succeeds不可能:UPDATE 语句失败,而 SELECT 成功
【发布时间】: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


【解决方案1】:

这并不能回答 为什么 一个有效而另一个无效,尽管 cmets 涉及到它,这是由于在查询计划中,SET 中的表达式可能是在WHERE 之前派生(这可能发生)。也许我们在上面有一个过于简化的查询,这就是为什么我们看不到一个明显的原因。

然而,为了避免它,一种方法是使用NULLIF

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

这意味着如果字符串中没有,,表达式将解析为NULL

【讨论】:

  • 这样就行了!我无法理解它,为什么 SQL 会尝试运行表达式,尽管对于不包含的行。这对我来说似乎效率很低,但正如你所提到的,这可能是引擎深处的东西,并且出于其他原因需要......
  • 这就是为什么我要求minimal reproducible example,@Kevin。我们无法运行您的 SQL,并且我复制您的问题的初步尝试失败了。
  • 我了解@Larnu,没有它就无法真正回答这个问题。我无法提供最小的可重现示例,因为我不知道是什么原因造成的。这只会让我意识到我不知道表面下发生的事情的一半。可能是这个表上的ClusteredColumnstoreIndex 引起的,或者统计有误。通过你的工作,我能够运行更新,所以我会保留它:)
  • 我已将查询计划添加到帖子中。我认为这解释了错误的来源。
【解决方案2】:

试试这个,以避免将负值传递给左函数:

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

【讨论】:

    猜你喜欢
    • 2017-06-14
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    • 2012-08-11
    • 1970-01-01
    • 2020-02-08
    • 2011-06-11
    相关资源
    最近更新 更多