oracle 身份证校验函数
1、正则表达式写法:
CREATE OR REPLACE FUNCTION Func_checkidcard (p_idcard IN VARCHAR2) RETURN INT
IS
v_regstr VARCHAR2 (2000);
v_sum NUMBER;
v_mod NUMBER;
v_checkcode CHAR (11) := '10X98765432';
v_checkbit CHAR (1);
v_areacode VARCHAR2 (2000) := '11,12,13,14,15,21,22,23,31,32,33,34,35,36,37,41,42,43,44,45,46,50,51,52,53,54,61,62,63,64,65,71,81,82,91,';
BEGIN
CASE LENGTHB (p_idcard)
WHEN 15
THEN -- 15位
IF INSTRB (v_areacode, SUBSTR (p_idcard, 1, 2) || ',') = 0 THEN
RETURN 0;
END IF; IF MOD (TO_NUMBER (SUBSTRB (p_idcard, 7, 2)) + 1900, 400) = 0
OR
(
MOD (TO_NUMBER (SUBSTRB (p_idcard, 7, 2)) + 1900, 100) <> 0
AND
MOD (TO_NUMBER (SUBSTRB (p_idcard, 7, 2)) + 1900, 4) = 0
)
THEN -- 闰年
v_regstr :=
'^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}$';
ELSE
v_regstr :=
'^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}$';
END IF; IF REGEXP_LIKE (p_idcard, v_regstr) THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
WHEN 18
THEN -- 18位
IF INSTRB (v_areacode, SUBSTRB (p_idcard, 1, 2) || ',') = 0 THEN
RETURN 0;
END IF; IF MOD (TO_NUMBER (SUBSTRB (p_idcard, 7, 4)), 400) = 0
OR
(
MOD (TO_NUMBER (SUBSTRB (p_idcard, 7, 4)), 100) <> 0
AND
MOD (TO_NUMBER (SUBSTRB (p_idcard, 7, 4)), 4) = 0
)
THEN -- 闰年
v_regstr :=
'^[1-9][0-9]{5}(19|20)[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9Xx]$';
ELSE
v_regstr :=
'^[1-9][0-9]{5}(19|20)[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}[0-9Xx]$';
END IF; IF REGEXP_LIKE (p_idcard, v_regstr) THEN
v_sum :=
( TO_NUMBER (SUBSTRB (p_idcard, 1, 1))
+ TO_NUMBER (SUBSTRB (p_idcard, 11, 1))
)
* 7
+ ( TO_NUMBER (SUBSTRB (p_idcard, 2, 1))
+ TO_NUMBER (SUBSTRB (p_idcard, 12, 1))
)
* 9
+ ( TO_NUMBER (SUBSTRB (p_idcard, 3, 1))
+ TO_NUMBER (SUBSTRB (p_idcard, 13, 1))
)
* 10
+ ( TO_NUMBER (SUBSTRB (p_idcard, 4, 1))
+ TO_NUMBER (SUBSTRB (p_idcard, 14, 1))
)
* 5
+ ( TO_NUMBER (SUBSTRB (p_idcard, 5, 1))
+ TO_NUMBER (SUBSTRB (p_idcard, 15, 1))
)
* 8
+ ( TO_NUMBER (SUBSTRB (p_idcard, 6, 1))
+ TO_NUMBER (SUBSTRB (p_idcard, 16, 1))
)
* 4
+ ( TO_NUMBER (SUBSTRB (p_idcard, 7, 1))
+ TO_NUMBER (SUBSTRB (p_idcard, 17, 1))
)
* 2
+ TO_NUMBER (SUBSTRB (p_idcard, 8, 1)) * 1
+ TO_NUMBER (SUBSTRB (p_idcard, 9, 1)) * 6
+ TO_NUMBER (SUBSTRB (p_idcard, 10, 1)) * 3;
v_mod := MOD (v_sum, 11);
v_checkbit := SUBSTRB (v_checkcode, v_mod + 1, 1); IF v_checkbit = upper(substrb(p_idcard,18,1)) THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
ELSE
RETURN 0;
END IF;
ELSE
RETURN 0; -- 身份证号码位数不对
END CASE;
EXCEPTION
WHEN OTHERS
THEN
RETURN 0;
END fn_checkidcard;
/
Show Err;
2、非正则表达式写法
Create Or Replace Function Func_checkIdcard (p_idcard in varchar2) Return Number
Is
v_sum Number;
v_mod Number;
v_length Number;
v_date Varchar2(10);
v_isDate Boolean;
v_isNumber Boolean;
v_isNumber_17 Boolean;
v_checkbit CHAR (1);
v_checkcode CHAR (11) := '10X98765432';
v_areacode VARCHAR2 (2000) := '11,12,13,14,15,21,22,23,31,32,33,34,35,36,37,41,42,43,44,45,46,50,51,52,53,54,61,62,63,64,65,71,81,82,91,'; --[isNumber]--
Function isNumber (p_string in varchar2) Return Boolean
Is
i number;
k number;
flag boolean;
v_length number;
Begin
/*
算法:
通过ASCII码判断是否数字,介于[48, 57]之间。
select ascii('0'),ascii('1'),ascii('2'),ascii('3'),ascii('4'),ascii('5'),ascii('6'),ascii('7'),ascii('8'),ascii('9') from dual;
*/ flag := True;
select length(p_string) into v_length from dual; for i in 1..v_length loop
k := ascii(substr(p_string,i,1));
if k < 48 or k > 57 then
flag := False;
Exit;
end if;
end loop; Return flag;
End isNumber; --[isDate]--
Function isDate (p_date in varchar2) Return Boolean
Is
v_flag boolean;
v_year number;
v_month number;
v_day number;
v_isLeapYear boolean;
Begin
--[初始化]--
v_flag := True; --[获取信息]--
v_year := to_number(substr(p_date,1,4));
v_month := to_number(substr(p_date,5,2));
v_day := to_number(substr(p_date,7,2)); --[判断是否为闰年]--
if (mod(v_year,400) = 0) Or (mod(v_year,100) <> 0 And mod(v_year,4) = 0) then
v_isLeapYear := True;
else
v_isLeapYear := False;
end if; --[判断月份]--
if v_month < 1 Or v_month > 12 then
v_flag := False;
Return v_flag;
end if; --[判断日期]--
if v_month in (1,3,5,7,8,10,12) and (v_day < 1 or v_day > 31) then
v_flag := False;
end if;
if v_month in (4,6,9,11) and (v_day < 1 or v_day > 30) then
v_flag := False;
end if;
if v_month in (2) then
if (v_isLeapYear) then
--[闰年]--
if (v_day < 1 or v_day > 29) then
v_flag := False;
end if;
else
--[非闰年]--
if (v_day < 1 or v_day > 28) then
v_flag := False;
end if;
end if;
end if; --[返回结果]--
Return v_flag;
End isDate;
Begin
/*
返回值说明:
-1 身份证号码位数不对
-2 身份证号码出生日期超出范围
-3 身份证号码含有非法字符
-4 身份证号码校验码错误
-5 身份证号码地区码非法
1 身份证号码通过校验
*/
--[长度校验]--
if p_idcard is null then
return -1;
end if ;
select lengthb(p_idcard) into v_length from dual;
if v_length not in (15,18) then
return -1;
end if; --[区位码校验]--
if instrb(v_areacode, substr(p_idcard, 1, 2)||',') = 0 then
return -5;
end if; --[格式化校验]--
if v_length = 15 then
v_isNumber := isNumber (p_idcard);
if not (v_isNumber) then
return -3;
end if;
elsif v_length = 18 then
v_isNumber := isNumber (p_idcard);
v_isNumber_17 := isNumber (substr(p_idcard,1,17));
if not ((v_isNumber) or (v_isNumber_17 and upper(substr(p_idcard,18,1)) = 'X')) then
return -3;
end if;
end if; --[出生日期校验]--
if v_length = 15 then
select ''||substr(p_idcard,7,6) into v_date from dual;
elsif v_length = 18 then
select substr(p_idcard,7,8) into v_date from dual;
end if;
v_isDate := isDate (v_date);
if not (v_isDate) then
return -2;
end if; --[校验码校验]--
if v_length = 18 then
v_sum :=
( TO_NUMBER (SUBSTRB (p_idcard, 1, 1))
+ TO_NUMBER (SUBSTRB (p_idcard, 11, 1))
)
* 7
+ ( TO_NUMBER (SUBSTRB (p_idcard, 2, 1))
+ TO_NUMBER (SUBSTRB (p_idcard, 12, 1))
)
* 9
+ ( TO_NUMBER (SUBSTRB (p_idcard, 3, 1))
+ TO_NUMBER (SUBSTRB (p_idcard, 13, 1))
)
* 10
+ ( TO_NUMBER (SUBSTRB (p_idcard, 4, 1))
+ TO_NUMBER (SUBSTRB (p_idcard, 14, 1))
)
* 5
+ ( TO_NUMBER (SUBSTRB (p_idcard, 5, 1))
+ TO_NUMBER (SUBSTRB (p_idcard, 15, 1))
)
* 8
+ ( TO_NUMBER (SUBSTRB (p_idcard, 6, 1))
+ TO_NUMBER (SUBSTRB (p_idcard, 16, 1))
)
* 4
+ ( TO_NUMBER (SUBSTRB (p_idcard, 7, 1))
+ TO_NUMBER (SUBSTRB (p_idcard, 17, 1))
)
* 2
+ TO_NUMBER (SUBSTRB (p_idcard, 8, 1)) * 1
+ TO_NUMBER (SUBSTRB (p_idcard, 9, 1)) * 6
+ TO_NUMBER (SUBSTRB (p_idcard, 10, 1)) * 3;
v_mod := MOD (v_sum, 11);
v_checkbit := SUBSTRB (v_checkcode, v_mod + 1, 1); if v_checkbit = upper(substrb(p_idcard,18,1)) then
return 1;
else
return -4;
end if;
else
return 1;
end if;
End Func_checkIdcard;
/
Show Err;
oracle 身份证校验函数的更多相关文章
- Oracle 身份证校验
SELECT SUBSTR('&AI', 0, 17) || TRANSLATE(DECODE(MOD(SUM(SUBSTR(WI, REGEXP_INSTR(WI, ' ', 1, I) + ...
- 完美实现身份证校验 js正则
注意: 1.只针对18为身份证号码进行校验,现在15位的应该很少了, 2.不区分xX大小写, 3.出生年份1900-2099,每月的天数也进行相关验证(考虑的闰月的情况), 4.校验规则详见,这个写的 ...
- Java 常用正则表达式,Java正则表达式,Java身份证校验,最新手机号码正则表达式
Java 常用正则表达式,Java正则表达式,Java身份证校验,最新手机号码校验正则表达式 ============================== ©Copyright 蕃薯耀 2017年11 ...
- Oracle的nvl函数和nvl2函数
一.基本语法 介绍一下oracle的nvl函数和nvl2函数. nvl函数 nvl函数基本语法为nvl(E1,E2),意思是E1为null就返回E2,不为null就返回E1. nvl2函数 nvl2函 ...
- Oracle 中 decode 函数用法
Oracle 中 decode 函数用法 含义解释:decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值) 该函数的含义如下:IF 条件=值1 THEN RETURN(翻译 ...
- 重写Oracle的wm_concat函数,自定义分隔符、排序
oracle中,wm_concat函数是一个聚合函数,和mysql中的group_concat函数类似,不过group_concat函数比较强大,可以定义分隔符和排序,当然所谓强大是相对的,这里假使我 ...
- 篇二:JS身份证校验
身份证校验 function identityCodeValid(code) { var city={11:"北京",12:"天津",13:"河北&q ...
- Oracle日期时间函数大全
ORACLE日期时间函数大全 TO_DATE格式(以时间:2007-11-02 13:45:25为例) Year: yy two digits 两位年 显示值:07 yyy three digits ...
- Oracle过程及函数的参数模式,In、out、in out模式
Oracle过程及函数的参数模式 In.out.in out模式 在Oracle中过程与函数都可以有参数,参数的类型可以指定为in.out.in out三种模式. 三种参数的具体说明,如下图所示: ( ...
随机推荐
- JsonException: Max allowed object depth reached while trying to export from type System.Single
在进行类转json字符串时,报错JsonException: Max allowed object depth reached while trying to export from type Sys ...
- Solr部署到Tomcat
1.版本选择 solr-5.3.1.tgz apache-tomcat-8.0.29.tar.gz 2.解压tomcat和solr [root@iZ23exixsjaZ solr]# .tar.gz ...
- 一段比较有意思的代码——介绍system verilog中的新增幅值语句
system verilog中新加了很多幅值语句,虽然都只适用于阻塞幅值,但是在某些场合中非常实用. 下面是一段有意思的代码,覆盖了一些用法. package definitions; typedef ...
- peer not authenticated error
问题背景 系统:OS X El Capitan,10.11.2 IDE:Android Studio 2.0 Preview Java:1.8.0_65 Gradle:2.3 clone了代码后,在i ...
- C++与零值比较
1.布尔值与零值的比较 if(flag)//if为真 if(!flag)//if为假 其它都为不良风格: if (flag == TRUE) ) if (flag == FALSE) ) 2.整形值与 ...
- Java 2D API - 1. 基本概念
Java 2D API扩展AWT包,对二维图形.文本及成像功能提供了支持,可用于开发复杂的界面.绘图软件和图像编辑器.Java 2D对象位于用户坐标空间(User coordinate space), ...
- Web前端工程师
前端开发,不仅仅是需要会写页面而已,还需要具备很多技能,现做如下总结: 会点设计,不要求精湛,处理图片,设计个小广告是要的: 精通HTML+CSS,并能快速处理各浏览器兼容问题: 熟练掌握Javasc ...
- linux查看父子进程
python多进程代码 http://blog.csdn.net/yfkiss/article/details/6729364 Linux下多线程查看工具(pstree.ps.pstack) tes ...
- spring 定时器Quartz
一.Quartz是什么 二. 核心接口 scheduler --- 核心调度器 Job --- 任务 JobDetail --- 任务描述 Tigger --- 触发器 三 . 核心接口之间 ...
- ASP.NET MVC 中将FormCollection与实体间转换方法
将Action动作中传递的FormCollection转变成对应的实体,可以使用Controller的TryUpdateModel()方法. public ActionResult Create(Fo ...