【问题标题】:Invalid length parameter passed to the SUBSTRING (when using charindex - only for certain char)传递给 SUBSTRING 的长度参数无效(使用 charindex 时 - 仅适用于某些 char)
【发布时间】:2018-04-18 10:33:59
【问题描述】:

我有一个数据库,其中大多数 testid 的括号中都有我想要提取的信息。所以我写了(简化版)

select 
case when wt.testid like '%(%)%' 
then substring(wt.testid, 
        charindex('(',wt.testid)+1, 
        (charindex(')',wt.testid) - charindex('(',wt.testid) - 1)
        )

工作得很好,但并非所有这些测试都具有这种格式,有些在下划线之后和空格之前具有此信息,

所以我添加了这个额外的部分

else substring(wt.testid, 
        charindex('_',wt.testid)+1, 
        (charindex(' ',wt.testid) - charindex('_',wt.testid) -1)
        ) 

但由于某种原因,这会导致“传递给 SUBSTRING 函数的长度参数无效。”

如果我删除 -1 则查询有效,这表明 -1 导致长度参数为负数,但查询的所有结果都有空格和下划线,并且当我通过时

p>
(charindex(' ',wt.testid) - charindex('_',wt.testid) -1)

在我的选择中,我总是得到正值,所以我不知道发生了什么。

【问题讨论】:

  • testid 中是否还有 包含空格和下划线但通过ONWHERE 子句谓词过滤掉的值?跨度>
  • 您可以通过在原始查询中显式过滤WHERE (charindex(' ',wt.testid) - charindex('_',wt.testid) -1) < 0 轻松找到违规值,然后更仔细地查看。对“我总是得到积极的价值观”的简单回应是“那么SUBSTRING 永远不会失败”,但确实如此,所以你的假设一定有缺陷。
  • 抱歉,没有看到这些 cmets,但 Damien_The_Unbeliever 的其他答案已经确定了! :)

标签: sql-server database


【解决方案1】:

即使您的过滤器意味着在您的结果集中只返回包含括号或下划线和空格格式的结果,SQL Server 也将保证不会急切地评估某些表达式并生成错误实际上对最终结果没有贡献的行。

通常可以通过明智地使用CASE 表达式来重新测试您认为已知的事实来解决这个问题:

select 
case when wt.testid like '%(%)%' 
then substring(wt.testid, 
        charindex('(',wt.testid)+1, 
        (charindex(')',wt.testid) - charindex('(',wt.testid) - 1)
        )
when wt.testid like '%!_% %' escape '!'
then substring(wt.testid, 
        charindex('_',wt.testid)+1, 
        (charindex(' ',wt.testid) - charindex('_',wt.testid) -1)
        )
end

如果您想分享 MS 似乎永远不会解决此问题的绝望,请参阅 SQL Server should not raise illogical errors

【讨论】:

  • 有趣。我开始得出类似的结论 - 它试图在我的最终结果中实际未包含的数据上运行此 substring 函数,就好像它在我的 'where' 子句生效之前进行评估一样。 escape 在这里做什么?
  • @ChrisA - 下划线是LIKE 中的通配符。但我想匹配文字下划线。 ESCAPE 表示您使用什么字符来转义 LIKE 表达式中的字符,以便它们具有字面意义。
猜你喜欢
  • 2021-11-29
  • 1970-01-01
  • 2014-03-01
  • 2016-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多