2013-12-18 1380 views
0

在查询中,我使用了几个SUBSTRING,CHARINDEX,LEN T-SQL函数。SQL Server查询传递给LEFT或SUBSTRING函数的长度参数无效

我得到一个错误:

Invalid length parameter passed to the LEFT or SUBSTRING function.`

好吧,我试图找出哪个记录​​导致无法对其进行过滤。

在WHERE语句,我尝试:

WHERE ... 
and mt.id between 1 and 200 

它失败。好的,我尝试缩小范围,改为:

WHERE ... 
and mt.id between 1 and 100 

它工作正常。好的,请尝试下一个范围:

WHERE ... 
and mt.id between 100 and 200 

它也可以正常工作!不要有任何错误。它爆炸我的大脑。 任何想法?

这是我尝试运行代码:

SELECT 
    * 
FROM [someTable] mt 
    INNER JOIN persons p p.ID = mt.personID 
    LEFT JOIN someTable2 pb 
    ON 
     SUBSTRING(pb.shortName, 0, CHARINDEX(' ', pb.shortName)) = mt.OSB 
     OR(
     SUBSTRING(mt.OSB, 0, CHARINDEX('/', mt.OSB)) 
    = SUBSTRING(pb.shortName, 0, CHARINDEX('/', pb.shortName)) 
    AND 
     '0' + SUBSTRING(mt.OSB, CHARINDEX('/', mt.OSB) + 1, LEN(mt.OSB)) 
    = SUBSTRING(pb.shortName, CHARINDEX('/', pb.shortName) + 1, 
    CHARINDEX(' ', pb.shortName) - CHARINDEX('/', pb.shortName) - 1)) 
WHERE mt.OSB IS NOT null AND mt.shet IS NOT NULL AND CHARINDEX('/', mt.OSB) > 0 
-- and mt.id between 1 and 200 
-- and mt.id between 1 and 100 
and mt.id between 100 and 200 
order by mt.id 

回答

0

我不会担心的范围内。你真正的问题是你的一个子串调用正试图占用比字段更多的字符。

的SQL Server不能保证以相同的顺序来评估的记录,所以其他一些记录可能当您使用1-200范围,但不是结果集的一部分来进行验证。

例如,下面的代码会导致一个问题,如果pb.shortName只有一个字:

SUBSTRING(pb.shortName, CHARINDEX('/', pb.shortName) + 1, 
       CHARINDEX(' ', pb.shortName) - CHARINDEX('/', pb.shortName) - 1) 

,因为你靠的字符串,并以两/是这将是一个问题该字符串中的特定顺序。

不知道您的应用程序/数据库的格式规则,这将很难帮助您进一步。

+0

我使用范围来找出哪条记录是错误的。从1-200到相同范围的ID失败。当我将它分成两个子集并分别运行时,id的相同范围会传递良好。这是问题。 – Alexandr

+0

这是问题,但它不是问题。 – ps2goat

0
1和200之间

有一些它是失败的子和CHARINDEX。尝试注释/取消注释列,并加入到达到这个错误记录。不要在1到200之间进行注释和mt.id 使用与您的查询在1和200之间相同的列来评估每个表,并查看记录截断的位置。 like

select SUBSTRING(pb.shortName, 0, CHARINDEX(' ', pb.shortName)) , 
     SUBSTRING(pb.shortName, 0, CHARINDEX('/', pb.shortName)), 

     SUBSTRING(pb.shortName, CHARINDEX('/', pb.shortName) + 1, 
       CHARINDEX(' ', pb.shortName) - CHARINDEX('/', pb.shortName) - 1) 
       from someTable2 pb 
       between pb.colname 1 and 200 

      similarly run for [someTable] mt