Oracle 检验身份证是否正确的存储过程

  1  --  Created on 2016/7/20 by ADMIN 
  2  declare
  3    --  Local variables here
  4    i  integer;
  5    --  Test statements here
  6     -- 声明数组变量
  7     -- 声明N数组 用于存放身份证系数(加权因子)7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2
  8    type N  is varray( 18of  integer;
  9    -- 声明S数组 用于存放求MOD得的余数'1','0','X','9','8','7','6','5','4','3','2'
 10    type S  is varray( 11of  varchar2( 11);
 11   JQYZ_N       N;  -- 将数组N的值赋予JQYZ_N
 12    YS_S         S;  -- 将数组S的值赋予YS_S
 13    ID_SUM        integer-- 身份证号分别乘以加权因子的总和
 14    ID_TMP_15_18  varchar2( 18);  -- 存储15位身份证转18位身份证年龄前+19
 15    ID_SUM_MOD    varchar2( 2);  -- 存储加权因子总和MOD11取余数,得到身份证最后一位检验位
 16    ID_Number     varchar2( 20);  -- 身份证号
 17    ID_Sex        varchar2( 10);  -- 存储性别,通过身份证判断性别
 18    ID_BirthDay   varchar2( 30);  -- 存储出生时间
 19    ID_Age        number-- 存储年龄
 20    ID_NumberEnd  varchar2( 20);  -- 存储最后得出的身份证号
 21    ID_ErrorCode  number-- 将错误代码返回,根据错误提示判断错误原因
 22 
 23    -- ID_ErrorCode返回1则身份证正确,返回其他负值则不正确
 24     -- 返回-1,系统错误,一般不会出现;
 25     -- 返回-2,身份证位数错误;
 26     -- 返回-3,出生日期错误或者身份证含有不正确的字符;
 27     -- 返回-4,检验位错误,只有18位身份证才能出现此错误;
 28 
 29    -- 只有正确的时候,性别和出生日期才能有值
 30 
 31    -- ID_NumberEnd是升级ID_Number得到的18位身份证号码,最后x大写
 32  begin
 33    -- 给ID_Number赋予任意一个身份证号
 34    ID_Number : =  ' 110101198906200054 ';
 35    -- 给ID_ErrorCode赋予初始值;
 36    ID_ErrorCode : =  1;
 37    -- 给加权因子赋值
 38    JQYZ_N : = N( 79105842163791058421);
 39    -- 给求MOD余数数组赋值
 40    YS_S : = S( ' 1 '' 0 '' X '' 9 '' 8 '' 7 '' 6 '' 5 '' 4 '' 3 '' 2 ');
 41    -- 初始ID_SUM
 42    ID_SUM : =  0;
 43    -- 开始判断执行
 44     if lengthb(ID_Number)  =  15  then
 45      -- 判断该身份证长度 15位则执行下面转换方法变成18位
 46       begin
 47       ID_TMP_15_18 : = substrb(ID_Number,  16||  ' 19 '  ||
 48                       substrb(ID_Number,  7);  -- 将15位身份证分割拼接成18位
 49         -- 循环执行身份证号与加权因子相乘之和
 50         for i  in  1 ..  17 loop
 51         ID_SUM : = ID_SUM  +
 52                   to_number(substrb(ID_TMP_15_18, i,  1))  * JQYZ_N(i);
 53        end loop;
 54        -- 求加权因子总和MOD11取余数,得到检验位
 55        ID_SUM_MOD : = YS_S(mod(ID_SUM,  11+  1);
 56        -- 判断该身份证号是男或者女 1男 2女
 57         select decode(mod(to_number(substrb(ID_TMP_15_18,  171)),  2),
 58                      0,
 59                      ' ',
 60                      ' ')
 61          into ID_Sex
 62          from dual;
 63        -- 截取出生时间
 64         /* ID_BirthDay := to_date('19'||substrb(ID_Number, 7, 6), 'yyyymmdd'); */
 65        select to_date(substrb(ID_TMP_15_18,  78),  ' yyyymmdd ')
 66          into ID_BirthDay
 67          from dual;
 68        -- 存储最后得出的身份证号
 69        ID_NumberEnd : = ID_TMP_15_18  || ID_SUM_MOD;
 70        begin
 71          -- 计算年龄
 72           select trunc(months_between(sysdate, ID_BirthDay)  /  12)
 73            into ID_Age
 74            from dual;
 75       exception
 76          when others  then
 77           ID_ErrorCode : =  - 3-- 出生日期错误或者身份证含有不正确的字符;
 78         end;
 79     exception
 80        when others  then
 81         ID_ErrorCode : =  - 3-- 出生日期错误或者身份证含有不正确的字符;
 82           return;
 83      end;
 84   elsif lengthb(ID_Number)  =  18  then
 85      begin
 86        -- 循环执行身份证号与加权因子相乘之和
 87         for i  in  1 ..  17 loop
 88         ID_SUM : = ID_SUM  + to_number(substrb(ID_Number, i,  1))  * JQYZ_N(i);
 89        end loop;
 90        -- 求加权因子总和MOD11取余数,得到检验位
 91        ID_SUM_MOD : = YS_S(mod(ID_SUM,  11+  1);
 92        -- 判断输入的身份证检验位与计算得到的是否一致
 93         if  upper(substrb(ID_Number,  - 1))  != ID_SUM_MOD  then
 94         ID_ErrorCode : =  - 4-- 返回-4,检验位错误,只有18位身份证才能出现此错误;
 95           return;
 96        end  if;
 97        -- 判断该身份证号是男或者女 1男 2女
 98         select decode(mod(to_number(substrb(ID_Number,  171)),  2),
 99                      0,
100                      ' ',
101                      ' ')
102          into ID_Sex
103          from dual;
104        -- 截取出生时间
105         select to_date(substrb(ID_Number,  78),  ' yyyymmdd ')
106          into ID_BirthDay
107          from dual;
108        -- 存储最后得出的身份证号
109        ID_NumberEnd : = ID_Number;
110        -- 计算年龄
111         begin
112          select trunc(months_between(sysdate, ID_BirthDay)  /  12)
113            into ID_Age
114            from dual;
115       exception
116          when others  then
117           ID_ErrorCode : =  - 3-- 出生日期错误或者身份证含有不正确的字符;
118         end;
119     exception
120        when others  then
121         ID_ErrorCode : =  - 3-- 出生日期错误或者身份证含有不正确的字符;
122           return;
123      end;
124    else
125     ID_ErrorCode : =  - 2-- 身份证位数错误;
126       return;
127    end  if;
128 exception
129    when others  then
130     ID_ErrorCode : =  - 1; -- 系统错误,一般不会出现;
131  end;

转载于:https://www.cnblogs.com/ljs05/p/5702560.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值