• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    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
        /*
        算法:
          通过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函数的使用方法示例
    上一篇:解决ORA-12170:TNS connect timeout occurred问题
    下一篇:oracle 取某个时间段的数据(每周几的上午几点到几点)
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

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