首页数据库oracle 身份证校验函数的实例代码

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

时间2024-02-28 16:54:03发布访客分类数据库浏览752
导读:收集整理的这篇文章主要介绍了oracle 身份证校验函数的实例代码,觉得挺不错的,现在分享给大家,也给大家做个参考。 1、正则表达式写法:CREATE OR REPLACE FUNCTI...
收集整理的这篇文章主要介绍了oracle 身份证校验函数的实例代码,觉得挺不错的,现在分享给大家,也给大家做个参考。

1、正则表达式写法:

CREATE OR REPLACE FUNCTION Func_checkIDCard (p_idcard IN VArchAR2) RETURN INTIS  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 NumberIs  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 中Contains 函数的用法
  • Oracle常用函数Trunc及Trunc函数用法讲解
  • Oracle中的translate函数和replace函数的用法详解
  • oracle中decode函数的使用方法示例

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: oracle 身份证校验函数的实例代码
本文地址: https://pptw.com/jishu/631691.html
Linux一键部署oracle安装环境脚本(推荐) centos7.7安装oracle11g脚本(推荐)

游客 回复需填写必要信息