侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

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

数据库  /  管理员 发布于 6年前   190

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 取某个时间段的数据(每周几的上午几点到几点)
    下一条:
    Oracle中多表关联批量插入批量更新与批量删除操作
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 分库分表的目的、优缺点及具体实现方式介绍(0个评论)
    • DevDB - 在 VS 代码中直接访问数据库(0个评论)
    • 在ubuntu系统中实现mysql数据存储目录迁移流程步骤(0个评论)
    • 在mysql中使用存储过程批量新增测试数据流程步骤(0个评论)
    • php+mysql数据库批量根据条件快速更新、连表更新sql实现(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2017-06
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-01
    • 2018-05
    • 2018-10
    • 2018-11
    • 2020-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2021-02
    • 2021-04
    • 2021-07
    • 2021-08
    • 2021-11
    • 2021-12
    • 2022-02
    • 2022-03
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-07
    • 2023-08
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-03
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客