TSQL提取产品描述中两逗号间带oz.容量值的SQL报错问题
原SQL报错核心原因
- 逻辑锚点完全错位:直接取全文第一个逗号的位置、全文第一个oz.的位置计算截取长度,和要求匹配的oz.两侧紧邻逗号规则没有对应关系
- 容易触发报错的典型场景:oz.出现在第一个逗号之前时,两个CHARINDEX的计算结果差值为负,导致SUBSTRING的长度参数非法;文本中不存在oz.时,CHARINDEX返回0,同样会出现长度参数为负的问题
- 根本问题:没有围绕oz.本身的相邻逗号做位置定位,用全局第一个匹配项做计算,很容易因为无关内容的干扰算错位置
可正常运行的匹配写法
这套逻辑会严格匹配两个逗号之间包裹oz.的片段,匹配不到时返回NULL,不会触发参数非法报错:
SELECT TRIM(BOTH ', ' FROM target_capacity_segment) AS ProductCapacity FROM CatalogManagement.Product CROSS APPLY ( -- 定位字符串中第一个oz.的位置,不存在时返回0 SELECT CHARINDEX('oz.', FullDescription) AS oz_first_pos ) AS base_pos CROSS APPLY ( -- 定位oz.左侧紧邻的逗号位置 SELECT CASE WHEN base_pos.oz_first_pos = 0 THEN 0 ELSE LEN(FullDescription) - CHARINDEX(',', REVERSE(LEFT(FullDescription, base_pos.oz_first_pos))) + 2 END AS left_comma_pos ) AS left_loc CROSS APPLY ( -- 定位oz.右侧紧邻的逗号位置 SELECT CASE WHEN base_pos.oz_first_pos = 0 THEN 0 ELSE base_pos.oz_first_pos + LEN('oz.') + CHARINDEX(',', RIGHT(FullDescription, LEN(FullDescription) - base_pos.oz_first_pos - LEN('oz.'))) - 1 END AS right_comma_pos ) AS right_loc CROSS APPLY ( -- 校验位置有效性,截取两个逗号之间的完整片段 SELECT SUBSTRING(FullDescription, left_loc.left_comma_pos, right_loc.right_comma_pos - left_loc.left_comma_pos + 1) AS target_capacity_segment WHERE left_loc.left_comma_pos > 0 AND right_loc.right_comma_pos > left_loc.left_comma_pos ) AS final_result
适配提示
- 文本中如果存在多个符合
, 数字 oz.,格式的片段,当前写法会取第一个匹配项,可根据实际业务需求调整锚点定位顺序 - 该写法兼容SQL Server 2017及以上的所有主流版本,无需依赖新版本专属函数
- 截取后用
TRIM去掉片段两端的逗号和空格,就能得到纯容量值,比如从, 15 oz.,中提取出15 oz.的目标结果
内容的提问来源于stack exchange,提问作者Stephen
相关产品推荐
相关产品推荐

