plsql校验身份证是否合法

原文地址:http://blog.csdn.net/ytfy12/article/details/11679625
功能需求:由于要对15000多参保职工进行身份证号的申报与检验,故需要做一个能够
          对身份证号有效性进行检验的软件功能,能够进行如下处理:
         1、检验身份证是否为空
         2、检验身份证长度是否为15或18位
         3、检验身份证的出生日期的有效性
         4、检验身份证的格式的有效性
         5、检验18位的身份号校验位的合法性,对15位加上校验位。
         6、以函数形式编写,以便进行调用使用,并返回非法类型。
实现环境:PL/SQL 7.0 
          编译了三个函数:sfzhcheck() 以字符型身份证号为参数,返回“正确”及各类非法错误类型
                          isnumber()  以字符型身份证号为参数,验证是否为合法格式,返回真假值
                          isdate()    以格式为2008-08-26的字符型日期为参数,验证是否为合法日期
                                      对年限制在了20世纪。
  
具体实现如下:
1、日期判断函数
create or replace isdate(rq in varchar2) return boolean is
  Result boolean;
  lyear integer;
  lmonth integer;
  lday integer;
  
begin
 result:=true;
  lyear:=to_number(substr(rq,1,4));
  lmonth:=to_number(substr(rq,6,2));
  lday:=to_number(substr(rq,9,2));
  if lyear>2000 or lyear<1900 then 
    Result:=false;
  end if;
    if lmonth<1 or lmonth>12 then 
   Result:=false;
  end if ;
   if mod(lyear,4)=0 and lyear/100<>Floor(lyear/100) or mod(lyear,400)=0 then 
       if (lmonth=2 and (lday<1 or lday>29)) then 
        Result:=false;
      end if;   
       else
    if  (lmonth=2 and (lday<1 or lday>28)) then 
       Result:=false;
  end if; 
  end if;
  if lmonth in (1,3,5,7,8,10,12) and (lday<1 or lday>31) then 
   Result:=false;
  end if;
  
    if lmonth in (4,6,9,11) and (lday<1 or lday>30) then 
   Result:=false;
  end if;
       return(Result);
 end isdate;
2、数字格式判断函数
create or replace IsNumber(Name in varchar2) return boolean is
  Result boolean;
  sz varchar2(10);
  pos integer;
  zf varchar2(1);
  cd integer;
  begin
sz:='0123456789';
Result:=true;
pos:=1;
cd:=length(name);
zf:=substr(name,pos,1);
while pos <= cd loop
if instr(sz,zf,1)!=0 then  
pos:=pos+1;
zf:=substr(name,pos,1);
else 
Result:=false;
return(Result);
end if;
end loop;
 return(Result);
end IsNumber;
3、身份证合法校验函数
create or replace sfzhcheck(sfzh in varchar2) return varchar2 is
  Result varchar2(30);
   err varchar2(30);
   sfzh1 varchar2(20);
   sfzh2 varchar2(20);
  sfzh_len number(2,0);
  rql varchar2(10);
   nn varchar2(36);
   ss varchar2(11);
  ll_Sum integer;
  i integer;
  ls_V varchar2(2);
   
 begin
  nn:= '070910050804020106030709100508040201';
  ss:= '10X98765432'; 
    err:='正确';
 sfzh1:=sfzh; 
 
 ---检验身份证是否为空
  if sfzh1 is null then 
    err:='身份证为空';
    result:=err;
    return(Result);
  end if ;
 --- 检验身份证长度是否满足
   sfzh_len:=length(trim(nvl(sfzh1,'')));
   
      if not  (sfzh_len=15 or sfzh_len=18) then 
        err:='身份证长度错'; 
      result:=err;
      return(Result);
     end if;
 
  ----检验身份证格式是否正确
 if not  (
 (sfzh_len = 15 and  IsNumber(sfzh1)) or 
 (sfzh_len = 18 And (IsNumber(sfzh1) or (IsNumber(substr(sfzh1,1, 17)) And Upper(substr(sfzh1,18, 1)) = 'X'))))  Then
   err:= '身份证格式错误';
    result:=err;
    return(Result);
   End If ; 
---检查身份证出生日期是否正确
if sfzh_len = 15 Then
   rql:= '19' || substr(sfzh1, 7, 2) || '-' || substr(sfzh1, 9, 2) || '-' || substr(sfzh, 11, 2);
Else
   rql :=substr(sfzh1, 7, 4) || '-' || substr(sfzh1, 11, 2) || '-' || substr(sfzh1, 13, 2);
End If;
 if  not isdate(rql) then 
      err:= '身份证出生日期错误';
    result:=err;
    return(Result);
 end if;
 ----性别没做检查可扩充用
 ----检查身份证校验位是否正确
sfzh2:=sfzh1;
 If sfzh_len = 15 Then 
  sfzh2 := substr(sfzh1,1, 6) ||+ '19' ||substr(sfzh1,7,9); 
 end if; 
 i:=1;
 ll_sum:=0;
while i<=17 loop
   ll_Sum :=ll_Sum+ to_number(substr(sfzh2, i, 1)) * to_number(substr(nn,(i-1)*2+1,2));
 i:=i+1;
end loop;
ls_V := substr(ss,(Mod(ll_Sum, 11) + 1),1);
If sfzh_len = 18 Then
   If upper(substr(sfzh1,18, 1)) <> upper(ls_V) Then
      err:= '身份证校验位不正确';
      result:=err;
  return(Result);  
   End If;
Else
   sfzh2:=sfzh2||ls_V;
End If; 
  result:=err;
  return(Result);   
   
end sfzhcheck;

猜你喜欢

转载自yhzhangdota.iteye.com/blog/2376557