栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 数据库 > Oracle

oracle 身份证校验函数的实例代码

Oracle 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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
    
     
    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
  
  --[长度校验]--
  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 '19'||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 身份证校验函数,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对考高分网网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/171032.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号