我有这样的查询,有时我们得到了错误消息: 传递给LEFT或SUBSTRING函数的长度参数无效。
我不明白何时以及为何? 我可以看到执行计划在不同的数据库和不同的SQL服务器版本之间有所不同,我已经意识到不同的SQL服务器版本为运行查询的顺序做了不同的选择。
如果查询运行正常或是否有一个很好的解释,这只是运气吗?
DECLARE @param NVARCHAR(5) = (SELECT descriptionname FROM Table1 WHERE
nameCode = 'SpecificCode')
SELECT Table2.TableID
,SUBSTRING(Name,1,(CHARINDEX(':',Name,1))-1) AS Name
,SUBSTRING(Name
,(CHARINDEX(':',Name,1)+1)
,((CHARINDEX(':',Name,(CHARINDEX(':',Name,1)+1)))-(CHARINDEX(':',Name,1)+1))
) AS Name2
FROM Table2
INNER JOIN TypeTable
ON Table2.ttID = TypeTable.ttID
WHERE Code = 'Test'
AND Name LIKE '%:%'
AND @param = 'True'
如果我们尝试下面的查询,它确实每次都有效。有什么重大的区别?
SELECT Table2.TableID AS [Id]
,SUBSTRING(Name,1,(CHARINDEX(':',Name,1))-1) AS Name
,SUBSTRING(Name
,(CHARINDEX(':',Name,1)+1)
,((CHARINDEX(':',Name,
(CHARINDEX(':',Name,1)+1)))-(CHARINDEX(':',Name,1)+1))
) AS Name2
FROM Table2
INNER JOIN TypeTable
ON Table2.ttID = TypeTable.ttID
WHERE Code = 'Test'
AND Name LIKE '%:%'
AND (SELECT descriptionname FROM Table1 WHERE nameCode = 'SpecificCode')
= 'True'
答案 0 :(得分:2)
面对像
这样非常脆弱的陈述SUBSTRING(Name ,
(CHARINDEX(':',Name,1)+1) ,
((CHARINDEX(':',Name,
(CHARINDEX(':',Name,1)+1)))-(CHARINDEX(':',Name,1)+1))
AS Name2
并且错误传递了无效的长度参数我不会从查看引擎开始。
相反,问题可能与数据有关。
查看documentation的长度参数
长度
是一个正整数或bigint表达式,指定了多少个 将返回表达式的字符。 如果长度为负, 生成错误并终止语句。如果总和 start和length大于in中的字符数 表达式,返回从start开始的整个值表达式。
我会查找会导致长度为负值的数据,并且我确定您会发现问题
e.g。
SELECT
Table2.TableID
Name
FROM Table2
INNER JOIN TypeTable
ON Table2.ttID = TypeTable.ttID
WHERE Code = 'Test'
AND Name LIKE '%:%'
AND @param = 'True'
and (CHARINDEX(':',Name,1)+1)))-(CHARINDEX(':',Name,1)+1)) < 0
如果你已经淘汰了这个。那么是的,你确实拥有problem
中提到的@Damien_The_Unbelieve comment最初我认为CTE可以做到这一点,但似乎优化器也可以在那里过度优化。所以达米恩further explains
我唯一依赖的是将查询拆分为两个不同的 查询并使用临时表或表变量进行存储 中间结果。