ORACLE对身份证号码处理相关的SQL【收藏】
2013-06-06 09:35
579 查看
/*ORACLE对身份证号码处理相关的SQL汇总 身份证号码算法及应用场景: 工作实践总结,与大家分享快乐,并请高人批评指正,努力改进: 目前我国大量存在着正在有效期的15位身份证,虽然国家在推行二代身份证,但尚未发现强行要求全国人民更换未到期的15位身份证的官方声明或公告。 扯远了:),总之合法的15位身份证号码将在今后一段时间内继续存在下去。 另外,项目中往往有着大量的历史数据,我们的一个系统中15位身份证所占比重很大,因此系统必须实现对两套身份证编码的职能处理,并支持另外一种特殊证件类型:军官证/警官证。本文重点讨论15位/18位身份证的处理问题 众所周知,我们现执行的身份证号码编码由公安部具体落实编码规则,有15位/18位两种,公安部以数学语言描述的方式公开了身份证编码规则和位码含义,但具体到计算机语言实现,需要开发人员自行根据算法设计。网上流传版本不少,不过繁杂而凌乱,且与应用集合描述的不多。现结合项目实践谈谈其处理和用途。 本文主要以oracle的SQL为例子,其他语言大家可以自行转换,道理都是一样的。 这里以ORACLE为例,其他数据库非常类似:*/ --1 号码转换问题 create or replace ID15TO18(p_OldID varchar2) return varchar2 is type TIArray is table of integer; type TCArray is table of char(1); Result varchar2(18); W TIArray; A TCArray; S integer; begin if Length(p_OldID) <> 15 OR NOT ISIDCARD(p_OldID) then --raise_application_error(-20999, '不是旧15位身份证号或者不是身份证号'); Result := p_OldID; else W := TIArray(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1); A := TCArray('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'); Result := SubStr(p_OldID, 1, 6) || '19' || SubStr(p_OldID, 7, 9); S := 0; begin for i in 1 .. 17 loop S := S + to_number(SubStr(Result, i, 1)) * W(i); end loop; exception when others then return ''; end; S := S mod 11; Result := Result || A(s + 1); end if; return(Result); end ID15TO18; --2 判断是否为身份证号码 create or replace isIDCard(p_IDcard varchar2) return boolean is IDcardlen integer; begin IDcardlen :=Length(p_IDcard); if (IDcardlen = 18 and IS_NUMBER(SubStr(p_IDcard, 1, IDcardlen-1)) and IS_DATE (substr(p_IDcard,7,8))) or (IDcardlen = 15 and IS_NUMBER(SubStr(p_IDcard, 1, IDcardlen)) and IS_DATE ('19' || subsTR(p_IDcard,7,6))) then return TRUE; ELSE return FALSE; end if; end isIDCard; --3 获取年龄,那获取生日类似,也就不show了 create or replace getAge(p_IDcard varchar2) return integer is IDcardlen integer; IDcardyear integer; begin IDcardlen :=Length(p_IDcard); if isidcard(p_IDcard)=1 and IDcardlen = 18 then IDcardyear := to_number(substr(p_IDcard,7,4)); end if; if isidcard(p_IDcard)=1 and IDcardlen = 15 then IDcardyear := to_number('19'||substr(p_IDcard,7,2)); end if; return to_number(to_char(sysdate,'yyyy'))-IDcardyear; end getAge; --3 获取年龄,精确到日 create or replace getAge(p_IDcard varchar2) return integer is IDcardlen integer; IDcardyear integer; begin IDcardlen :=Length(p_IDcard); if isidcard(p_IDcard)=1 and IDcardlen = 18 then IDcardyear := to_number(substr(p_IDcard,7,8)); end if; if isidcard(p_IDcard)=1 and IDcardlen = 15 then IDcardyear := to_number('19'||substr(p_IDcard,7,6)); end if; return to_number(to_char(sysdate,'yyyyMMdd'))-IDcardyear; end getAge; --4 获取性别 create or replace getSex(p_IDcard varchar2) return varchar2 is IDcardlen integer; begin IDcardlen :=Length(p_IDcard); if isidcard(p_IDcard)<>1 then return null; end if; if IDcardlen = 18 and Substr(p_IDcard,17,1) in (1,3,5,7,9) then return ('男'); end if; if IDcardlen = 18 and Substr(p_IDcard,17,1) in (2,4,6,8,0)then return ('女'); end if; if IDcardlen = 15 and Substr(p_IDcard,15,1) in (1,3,5,7,9) then return ('男'); end if; if IDcardlen = 15 and Substr(p_IDcard,15,1) in (2,4,6,8,0)then return ('女'); end if; end getSex; /* (三)总结用途 主要结合某实际项目,说三点: (1)实现15位/18位身份证号码智能登录 登录时,如果库里的是15位,系统用18位号码登录,应提示相关信息,辅助完成系统登录。 反之,提示用户号码输入不正确。 (2)自动升级库中的身份证号码从15位到18位 这个当然不能轻易机械的升级了,不过如果有重复数据时,判断重复数据,保留最新号码信息绝对是个好办法,如同时存在15位和18位,是否可以留18位就可以了? (3)智能校验:判断身份证输入,以及关联的性别、出生年月等是否正确 按公安部门发布的号码规则校验,当然是有效和有用的:)*/
相关文章推荐
- ORACLE对身份证号码处理相关的SQL汇总
- ORACLE对身份证号码处理相关的SQL汇总
- delphi 身份证号码相关处理单元
- 身份证号码相关处理单元及例程
- oracle解析身份证号码.sql
- 处理导出到EXCEL时,身份证号码的问题:mso-number-format
- Oracle中的数值处理相关函数介绍
- [推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)
- Oracle 顺序控制,异常处理,动态sql
- 【Oracle脚本】Oracle进程相关的SQL脚本
- Oracle 10g处理例外(即sql异常)学习一——预定义例外,即常见例外
- ORACLE应用调优:请避免SQL做大量循环逻辑处理
- Oracle 常用SQL --收藏
- 如何处理Oracle中TEMP表空间满的问题(含查询表空间SQL)
- Oracle的SQL语句中如何处理‘&’符号
- Oracle EBS-SQL (INV-6):检查监督帐户别名处理.sql
- SQL自增字段的相关总结-(主要SqlServe,Oracle)
- 【Oracle】PL/SQL 非预定义异常、自定义异常处理、RAISE_APPLICATION_ERROR
- Oracle根据身份证号码判断性别,年龄
- 在Oracle 9i中修改表的结构的相关sql语句