数据库教程:oracle 身份证校验函数的实例代码

1、正则表达式写法: create or replace function func_checkidcard (p_idcard in varchar2) return in

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   身份证号码地区码非法     身份证号码通过校验    */    --[长度校验]--    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 身份证校验函数,希望对大家有所帮助

需要了解更多数据库技术:oracle 身份证校验函数的实例代码,都可以关注数据库技术分享栏目—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/dtteaching/796798.html

(0)
上一篇 2021年9月11日
下一篇 2021年9月11日

精彩推荐