SQL Server 2012中SUBSTRING结合PATINDEX提取子串长度计算报错问题
问题分析与解决
报错原因
你遇到的报错核心是部分符合WHERE条件的行中,ItemCode没有包含-分隔符。
当PATINDEX('%[-]%', ItemCode)找不到匹配的-时,会返回0,此时0 - 6 = -6。而SQL Server的SUBSTRING函数要求第三个参数(截取长度)必须是大于0的整数,传入负数就会触发报错。
虽然你用LEFT(ItemCode, 5) = '99XXX'过滤了数据,但实际表中可能存在前5位是99XXX,但后续没有-的异常行,导致PATINDEX返回0。
验证异常数据
你可以先执行以下语句,找出这些不符合格式的异常行:
SELECT ItemCode FROM TableName WHERE LEFT(ItemCode, 5) = '99XXX' AND PATINDEX('%[-]%', ItemCode) = 0
修复后的SQL语句
方法1:处理异常情况,避免负数参数
通过CASE判断确保截取长度为正:
SELECT SUBSTRING(ItemCode, 6, CASE WHEN PATINDEX('%[-]%', ItemCode) >= 6 THEN PATINDEX('%[-]%', ItemCode) - 6 ELSE 0 END), PATINDEX('%[-]%', ItemCode), ItemCode FROM TableName WHERE LEFT(ItemCode, 5) = '99XXX'
方法2:利用固定长度规则(更高效)
既然你明确-前固定是11个字符,目标内容就是第6位开始的6个字符,直接写固定长度更简洁:
SELECT SUBSTRING(ItemCode, 6, 6), ItemCode FROM TableName WHERE LEFT(ItemCode, 5) = '99XXX' AND LEN(ItemCode) >= 11 -- 额外判断确保前11位存在
内容的提问来源于stack exchange,提问作者Bibendum
相关产品推荐
相关产品推荐

