“无效的长度参数传递给 LEFT 或 SUBSTRING 函数”错误的消失行为

J.D*_*.D. 7 sql-server-2008 sql-server

我遇到了“传递给 LEFT 或 SUBSTRING 函数的长度参数无效”错误,但是当我包含要传递给这些函数的列时,它会消失并且查询有效,有什么线索吗?

不起作用:

SELECT 
  SQT.QUOTATIONID, 
  UPPER(LEFT(Email.LOCATOR, CHARINDEX('@', Email.Locator) - 1)) AS Manager
  --, Email.LOCATOR
FROM SALESQUOTATIONTABLE AS SQT
INNER JOIN HCMWORKER AS H
    ON SQT.WORKERSALESRESPONSIBLE = H.RECID
INNER JOIN DIRPARTYTABLE AS D
    ON H.PERSON = D.RECID
INNER JOIN LOGISTICSELECTRONICADDRESS AS Email
    ON D.PRIMARYCONTACTEMAIL = Email.RECID
Run Code Online (Sandbox Code Playgroud)

传递给 LEFT 或 SUBSTRING 函数的长度参数无效

作品:

SELECT 
  SQT.QUOTATIONID, 
  UPPER(LEFT(Email.LOCATOR, CHARINDEX('@', Email.Locator) - 1)) AS Manager 
  , Email.LOCATOR
FROM SALESQUOTATIONTABLE AS SQT
INNER JOIN HCMWORKER AS H
    ON SQT.WORKERSALESRESPONSIBLE = H.RECID
INNER JOIN DIRPARTYTABLE AS D
    ON H.PERSON = D.RECID
INNER JOIN LOGISTICSELECTRONICADDRESS AS Email
    ON D.PRIMARYCONTACTEMAIL = Email.RECID
Run Code Online (Sandbox Code Playgroud)

这是连续可重复的,我对查询所做的唯一更改包括“Email.LOCATOR”列。这个查询已经工作了多年,今天只是随机停止工作。我很确定这是一个数据问题,但仍然困惑为什么选择 Email.LOCATOR 列可以解决这个问题。

ype*_*eᵀᴹ 9

我认为这个问题类似于这个问题:TSQL 函数中的奇怪行为(带有 int 变量或 NULL 的参数表现不同)?

特别是 Aaron Bertrand 在他的回答中提到的内容:

...因为在尝试计算之前您不能总是依赖 SQL Server 过滤行

我认为发生的事情是Email.Locator有些值不包含@. 处理这些值时, theCHARINDEX()为 0 并且LEFT()使用 parameter 调用-1,因此抛出错误。

但是为什么在一个查询而不是另一个查询中抛出错误?这可能是因为这两个查询是用不同的计划执行的。优化器选择不同的计划(由于额外的列或由于与上个月不同的统计数据或出于任何原因),并且在连接到其他表之前读取列的所有值(并完成计算)。


为了避免这个问题,我建议你使用CASE,替换

LEFT(Email.Locator, CHARINDEX('@', Email.Locator) - 1)
Run Code Online (Sandbox Code Playgroud)

和:

LEFT(Email.Locator, CASE WHEN CHARINDEX('@', Email.Locator) > 0 
                         THEN CHARINDEX('@', Email.Locator) - 1
                         ELSE 0
                    END)
Run Code Online (Sandbox Code Playgroud)

  • 当输出中包含另一列时,可能需要查找,或者在这种情况下有更好的覆盖索引...... (2认同)
  • 是的,执行的逻辑顺序是`FROM - WHERE - GROUP BY - HAVING - SELECT - ORDER BY`。但这只是执行的逻辑顺序。优化器可以自由选择不同的路径,只要结果与遵循逻辑顺序的结果相同。如果所有值都有@,那么就不会有问题。有些人认为这种行为是一个错误,我认为有一个关于它的 Connect 项目。 (2认同)