溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

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

發(fā)布時(shí)間:2020-10-10 20:23:13 來(lái)源:腳本之家 閱讀:204 作者:醉夢(mèng)洛 欄目:數(shù)據(jù)庫(kù)

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

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

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

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
    /*
    算法:
      通過(guò)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
  /*
  返回值說(shuō)明:
    -1   身份證號(hào)碼位數(shù)不對(duì)
    -2   身份證號(hào)碼出生日期超出范圍
    -3   身份證號(hào)碼含有非法字符
    -4   身份證號(hào)碼校驗(yàn)碼錯(cuò)誤
    -5   身份證號(hào)碼地區(qū)碼非法
   身份證號(hào)碼通過(guò)校驗(yàn)
  */
  --[長(zhǎng)度校驗(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ù),希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)億速云網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI