PL/pgSQL函数中TRIM、SUBSTRING未生效引发整数转换报错问题
问题根因
你的trim、substring处理逻辑完全没有执行,核心原因是条件分支的正则规则缺失边界锚定+判断顺序颠倒,高优先级的第一个分支提前拦截了所有包含4位连续数字的输入,根本不会走到后续带字符串处理的分支:
- 第一个IF分支的正则
_date ~ '[0-9]{4}'没有加字符串首尾匹配标记,只要文本任意位置存在4个连续数字就会判定为真。传入'1980ca'这类带后缀的参数时,字符串本身包含1980四个连续数字,会直接命中第一个分支,直接尝试把带ca后缀的原始字符串转int类型,自然触发类型转换错误。 - 分支判断顺序逻辑倒置:带
ca后缀、带年份偏移的特殊格式,比纯4位数字的通用格式匹配范围更小,应该放在判断链的最前面,否则会被通用规则提前拦截。
修正方案
给所有格式匹配的正则加上^(字符串开头锚定)、$(字符串结尾锚定),确保只有完全符合格式的字符串才进入对应分支,同时调整分支判断顺序,优先匹配特殊格式,最后匹配通用纯数字格式,修正后的函数如下:
CREATE FUNCTION date2datetuple (_date text) RETURNS datetuple AS $BODY$ BEGIN -- 优先匹配带ca后缀的模糊年份格式 IF _date ~ '^[0-9]{4}ca$' THEN RETURN (trim(trailing 'ca' from _date)::int, trim(trailing 'ca' from _date)::int); -- 匹配带前后偏移的年份区间格式 ELSIF _date ~ '^[0-9]{6}$' THEN RETURN (substring(_date from '^[0-9]{4}')::int - substring(_date from '[0-9]{2}$')::int, substring(_date from '^[0-9]{4}')::int + substring(_date from '[0-9]{2}$')::int); -- 最后匹配纯4位数字的精确年份格式 ELSIF _date ~ '^[0-9]{4}$' THEN RETURN (_date::int, _date::int); -- 可选:增加非法格式抛错逻辑,避免隐式转换问题 ELSE RAISE EXCEPTION '非法日期格式输入: %', _date; END IF; END; $BODY$ LANGUAGE plpgsql;
修正后传入
'1980ca'时,会正确命中第一个特殊格式分支,执行trim逻辑去掉后缀后再转int,不会再出现类型转换错误。
内容的提问来源于stack exchange,提问作者eslukas
相关产品推荐
相关产品推荐

