Oracle存储过程中不使用REGEXP校验CHAR入参的MON-YY日期格式
无正则的PL/SQL校验实现方案
核心校验逻辑拆解(完全不依赖正则语法)
- 优先处理CHAR定长类型的固有问题:CHAR入参会自动在不足长度的位置补尾随空格,需先用
TRIM()去除首尾空格,避免合法值被误判 - 基础长度校验:合法MON-YY格式总长度固定为6(3位月份+1位分隔符+2位年份),TRIM后字符串长度不等于6直接判定非法
- 分隔符位置校验:固定字符串第4位必须为连字符
-,通过SUBSTR()截取位置值判断,斜杠、其他符号出现在该位置直接拦截 - 月份合法性校验:严格匹配12个大写的标准月份缩写,非列表内的字符组合直接判定非法
- 年份合法性校验:截取最后两位字符,通过内置
TRANSLATE()函数判断是否为纯数字,含非数字字符直接判定非法
完整可运行存储过程代码
create or replace procedure p_date(prd char) AS p_err exception; v_trimmed_str varchar2(100); v_year_part varchar2(2); BEGIN -- 处理CHAR定长类型的自动补空格问题 v_trimmed_str := TRIM(prd); -- 固定长度校验:合法MON-YY总长度为6,长度不符直接判非法 IF LENGTH(v_trimmed_str) != 6 THEN RAISE p_err; END IF; -- 分隔符校验:第4位必须是连字符-,拦截斜杠等其他分隔符 IF SUBSTR(v_trimmed_str, 4, 1) != '-' THEN RAISE p_err; END IF; -- 月份合法性校验:严格匹配12个大写的标准月份缩写 IF SUBSTR(v_trimmed_str, 1, 3) NOT IN ( 'JAN','FEB','MAR','APR','MAY','JUN', 'JUL','AUG','SEP','OCT','NOV','DEC' ) THEN RAISE p_err; END IF; -- 年份合法性校验:截取最后两位,确认是纯数字 v_year_part := SUBSTR(v_trimmed_str, 5, 2); -- TRANSLATE将数字字符全部替换为空,剩余内容非空则说明含非数字字符 IF TRANSLATE(v_year_part, 'x0123456789', 'x') IS NOT NULL THEN RAISE p_err; END IF; -- 全部校验通过,可执行业务逻辑 DBMS_OUTPUT.PUT_LINE('Format check passed: ' || v_trimmed_str); EXCEPTION WHEN p_err THEN -- 修正原代码笔误:将错写的DBMS_OUPUT调整为DBMS_OUTPUT DBMS_OUTPUT.PUT_LINE('Invalid date format'); END; /
非法场景覆盖验证
- 斜杠分隔的
JAN/99:第4位字符为/,被分隔符校验拦截 - 非标准月份的
ABD-99:前3位不在合法月份列表内,被月份校验拦截 - 长度不符的
JAN-9(5位)、JAN-999(7位):被长度校验拦截 - 小写月份的
jan-99、分隔符位置错位的JA-N99:被严格匹配规则拦截 - 年份含非数字字符的
JAN-AB、JAN-A9:被TRANSLATE数字校验拦截 - CHAR类型自动补尾随空格的入参:通过TRIM逻辑统一处理,避免合法值误判
内容的提问来源于stack exchange,提问作者SQLMAN
相关产品推荐
相关产品推荐

