Oracle驗證身份證號碼有效性

廢話不多說,直接上代碼

create or replace function f_get_idcard_address(p_idcode in varchar2)
/*
   Create By yuxiao 
   2018-04-27
*/
  return varchar is
  v_area varchar2(50);
begin
  select area
    into v_area
    from yuxiao.idcard
   where idcode = substr(p_idcode, 1, 6);
  return v_area;
exception
  when others then
    return null;
end f_get_idcard_address;
create or replace function f_get_idcard_birthday(p_birthday in varchar2)
/*
   Create By yuxiao 
   2018-04-27
*/
  return varchar is
begin
  return to_char(to_date(substr(p_birthday, 7, 8), 'yyyymmdd'),
                 'yyyy"年"mm"月"dd"日"');
exception
  when others then
    return null;
end f_get_idcard_birthday;
create or replace function f_get_idcard_sex(p_sex in varchar2)
/*
   Create By yuxiao 
   2018-04-27
*/
  return varchar is
begin
  return case mod(substr(p_sex, 17, 1), 2) when 1 then '男' when 0 then '女' else null end;
exception
  when others then
    return null;
end f_get_idcard_sex;
create or replace function f_get_idcard_check(p_idcode in varchar2) return varchar is
/*
   Create By yuxiao 
   2018-04-27
*/
  type tiarray is table of integer;
  type tcarray is table of char(1);
  w    tiarray; --數字數組
  a    tcarray; --字符數組
  s    number;
begin
  w    := tiarray(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1);
  a    := tcarray('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
  s    := 0;
  begin
    for i in 1 .. 17 loop
      s := s + to_number(substr(p_idcode, i, 1)) * w(i);
    end loop;
  exception
    when others then
    return '';
  end;
  s     := s mod 11;
  if a(s + 1) = substr(p_idcode,-1) then
    return 'ok';
  else
    return a(s + 1);
  end if;
exception
  when others then
    return null;
end f_get_idcard_check;
create or replace procedure prc_get_idcard_info(p_idcard in varchar2,
                                                out_str  out varchar2) is
/*
   Create By yuxiao 
   2018-04-27
*/
  v_address  varchar2(50);
  v_birthday varchar2(50);
  v_sex      varchar2(10);
  v_check    varchar2(10);
  v_out_str  varchar2(2000);
  err_cnt    number := 0;
begin
  --格式校驗
  if not regexp_like(nvl(p_idcard,'1'),'^\d{17}(\d|X)$') then
    v_out_str := '無效的格式!' || v_check;
    out_str   := out_str || v_out_str;
    err_cnt   := err_cnt + 1;
    return;
  end if;

  --歸屬地
  v_address := f_get_idcard_address(p_idcard);
  if v_address is null then
    v_out_str := '無效證件號碼! 1~6位輸入有誤';
    out_str   := out_str || v_out_str;
    err_cnt   := err_cnt + 1;
    return;
  end if;

  --出生日
  v_birthday := f_get_idcard_birthday(p_idcard);
  if v_birthday is null then
    v_out_str := '無效證件號碼! 7~14位(出生日期)輸入有誤';
    out_str   := out_str || v_out_str;
    err_cnt   := err_cnt + 1;
    return;
  end if;

  --性別
  v_sex := f_get_idcard_sex(p_idcard);
  if v_sex is null then
    v_out_str := '無效證件號碼! 第17位輸入有誤';
    out_str   := out_str || v_out_str;
    err_cnt   := err_cnt + 1;
    return;
  end if;

  --末位校驗碼
  v_check := f_get_idcard_check(p_idcard);
  if v_check != 'ok' then
    v_out_str := '無效證件號碼! 最末位應該是' || v_check;
    out_str   := out_str || v_out_str;
    err_cnt   := err_cnt + 1;
    return;
  end if;
  
  if err_cnt = 0 then
    v_out_str := v_out_str || '身份證號:' || p_idcard || chr(10);
    v_out_str := v_out_str || '證件地址:' || v_address || chr(10);
    v_out_str := v_out_str || '生    日:' || v_birthday || chr(10);
    v_out_str := v_out_str || '性    別:' || v_sex || chr(10);
    out_str   := v_out_str;
  end if;
exception
  when others then
    v_out_str := '無效證件號碼!';
    out_str   := v_out_str;
end prc_get_idcard_info;

運行效果如下:




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章