中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

oracle 身份證校驗函數的實例代碼

發布時間:2020-10-10 20:23:13 來源:腳本之家 閱讀:205 作者:醉夢洛 欄目:數據庫

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 身份證校驗函數,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對億速云網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

翁牛特旗| 顺义区| 曲靖市| 天等县| 新宁县| 宿松县| 文化| 麟游县| 老河口市| 黄梅县| 桦川县| 汉源县| 临安市| 邵阳市| 西畴县| 乐都县| 土默特右旗| 北海市| 万山特区| 左权县| 扶风县| 大港区| 广丰县| 宜章县| 利川市| 成都市| 祁东县| 嘉鱼县| 塘沽区| 宕昌县| 武汉市| 长丰县| 黄大仙区| 丁青县| 肇庆市| 霍山县| 望谟县| 安宁市| 阿城市| 水富县| 沁阳市|