佳木斯湛栽影视文化发展公司

主頁 > 知識庫 > oracle 身份證校驗(yàn)函數(shù)的實(shí)例代碼

oracle 身份證校驗(yàn)函數(shù)的實(shí)例代碼

熱門標(biāo)簽:AI電銷 百度競價排名 網(wǎng)站排名優(yōu)化 鐵路電話系統(tǒng) Linux服務(wù)器 地方門戶網(wǎng)站 服務(wù)外包 呼叫中心市場需求

1、正則表達(dá)式寫法:

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;  -- 身份證號碼位數(shù)不對
  END CASE;
EXCEPTION
  WHEN OTHERS
  THEN
   RETURN 0;
END fn_checkidcard;
/
Show Err;

2、非正則表達(dá)式寫法

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碼判斷是否數(shù)字,介于[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;
     
    --[返回結(jié)果]--
    Return v_flag;
  End isDate;
Begin
  /*
  返回值說明:
    -1   身份證號碼位數(shù)不對
    -2   身份證號碼出生日期超出范圍
    -3   身份證號碼含有非法字符
    -4   身份證號碼校驗(yàn)碼錯誤
    -5   身份證號碼地區(qū)碼非法
   身份證號碼通過校驗(yàn)
  */
  --[長度校驗(yàn)]--
  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;
   
  --[區(qū)位碼校驗(yàn)]--
  if instrb(v_areacode, substr(p_idcard, 1, 2)||',') = 0 then
    return -5;
  end if;
   
  --[格式化校驗(yàn)]--
  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;
   
  --[出生日期校驗(yàn)]--
  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;
   
  --[校驗(yàn)碼校驗(yàn)]--
  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;

總結(jié)

以上所述是小編給大家介紹的oracle 身份證校驗(yàn)函數(shù),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!

您可能感興趣的文章:
  • Oracle 中Contains 函數(shù)的用法
  • Oracle常用函數(shù)Trunc及Trunc函數(shù)用法講解
  • Oracle中的translate函數(shù)和replace函數(shù)的用法詳解
  • oracle中decode函數(shù)的使用方法示例

標(biāo)簽:銅川 衡水 湘潭 黃山 湖南 蘭州 崇左 仙桃

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《oracle 身份證校驗(yàn)函數(shù)的實(shí)例代碼》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    滕州市| 临城县| 沙田区| 保靖县| 攀枝花市| 郁南县| 漳浦县| 三河市| 肃南| 枣阳市| 永吉县| 都安| 南京市| 柳州市| 左贡县| 鄂尔多斯市| 苏尼特右旗| 盐池县| 满城县| 含山县| 丰都县| 库尔勒市| 垣曲县| 益阳市| 东方市| 浦北县| 公安县| 庆元县| 静乐县| 乃东县| 湘乡市| 东丰县| 民丰县| 云龙县| 永州市| 哈密市| 湘阴县| 台中市| 绥棱县| 濮阳县| 上蔡县|