ORACLE對身份證號碼處理相關的SQL【收藏】


/*ORACLE對身份證號碼處理相關的SQL匯總 

身份證號碼算法及應用場景:

         工作實踐總結,與大家分享快樂,並請高人批評指正,努力改進:

          目前我國大量存在着正在有效期的15位身份證,雖然國家在推行二代身份證,但尚未發現強行要求全國人民更換未到期的15位身份證的官方聲明或公告。
          扯遠了:),總之合法的15位身份證號碼將在今后一段時間內繼續存在下去。

         另外,項目中往往有着大量的歷史數據,我們的一個系統中15位身份證所占比重很大,因此系統必須實現對兩套身份證編碼的職能處理,並支持另外一種特殊證件類型:軍官證/警官證。本文重點討論15位/18位身份證的處理問題

         眾所周知,我們現執行的身份證號碼編碼由公安部具體落實編碼規則,有15位/18位兩種,公安部以數學語言描述的方式公開了身份證編碼規則和位碼含義,但具體到計算機語言實現,需要開發人員自行根據算法設計。網上流傳版本不少,不過繁雜而凌亂,且與應用集合描述的不多。現結合項目實踐談談其處理和用途。
         本文主要以oracle的SQL為例子,其他語言大家可以自行轉換,道理都是一樣的。

這里以ORACLE為例,其他數據庫非常類似:*/

--1 號碼轉換問題        
create or replace ID15TO18(p_OldID varchar2) return varchar2 is
   type TIArray is table of integer; 
   type TCArray is table of char(1); 
   Result varchar2(18); 
   W TIArray; 
   A TCArray; 
   S integer; 
begin 
   if Length(p_OldID) <> 15 OR  NOT ISIDCARD(p_OldID) then 
--raise_application_error(-20999, '不是舊15位身份證號或者不是身份證號'); 
   Result := p_OldID;
   else

   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'); 
   Result := SubStr(p_OldID, 1, 6) || '19' || SubStr(p_OldID, 7, 9); 

   S := 0; 
   begin 
      for i in 1 .. 17 loop 
      S := S + to_number(SubStr(Result, i, 1)) * W(i); 
      end loop; 
      exception 
      when others then 
      return ''; 
   end; 
      S := S mod 11; 
      Result := Result || A(s + 1); 

   end if; 

   return(Result); 
end ID15TO18;


--2 判斷是否為身份證號碼
create or replace isIDCard(p_IDcard varchar2) return boolean is

IDcardlen integer;

begin 

  IDcardlen :=Length(p_IDcard);  
   
  if (IDcardlen = 18 and IS_NUMBER(SubStr(p_IDcard, 1, IDcardlen-1))
                     and IS_DATE (substr(p_IDcard,7,8)))
                    or                    
     (IDcardlen = 15 and IS_NUMBER(SubStr(p_IDcard, 1, IDcardlen))
                     and IS_DATE ('19' || subsTR(p_IDcard,7,6)))          
  then

      return TRUE;
      
      ELSE
         return FALSE;
   end if;
      
end isIDCard; 


--3 獲取年齡,那獲取生日類似,也就不show了
create or replace getAge(p_IDcard varchar2) return integer is

IDcardlen integer;
IDcardyear integer;

begin 

  IDcardlen :=Length(p_IDcard);  
  
   if isidcard(p_IDcard)=1 and IDcardlen = 18 then
     IDcardyear := to_number(substr(p_IDcard,7,4));  
  end if;
  if isidcard(p_IDcard)=1 and IDcardlen = 15 then  
     IDcardyear := to_number('19'||substr(p_IDcard,7,2));
  end if;
   
  return  to_number(to_char(sysdate,'yyyy'))-IDcardyear;   
   
      
end getAge;

--3 獲取年齡,精確到日
create or replace getAge(p_IDcard varchar2) return integer is

IDcardlen integer;
IDcardyear integer;

begin 

  IDcardlen :=Length(p_IDcard);  
  
   if isidcard(p_IDcard)=1 and IDcardlen = 18 then
     IDcardyear := to_number(substr(p_IDcard,7,8));  
  end if;
  if isidcard(p_IDcard)=1 and IDcardlen = 15 then  
     IDcardyear := to_number('19'||substr(p_IDcard,7,6));
  end if;
   
  return  to_number(to_char(sysdate,'yyyyMMdd'))-IDcardyear;   
   
      
end getAge;

--4 獲取性別

create or replace getSex(p_IDcard varchar2) return varchar2 is

IDcardlen integer;

begin 

  IDcardlen :=Length(p_IDcard);  
  
  if isidcard(p_IDcard)<>1 then
      return null; 
  end if;
   
      if IDcardlen = 18 and Substr(p_IDcard,17,1) in (1,3,5,7,9) then  
          return ('');
      end if;  
     if IDcardlen = 18 and Substr(p_IDcard,17,1) in (2,4,6,8,0)then  
              return ('');
      end if;  

      if IDcardlen = 15 and  Substr(p_IDcard,15,1) in (1,3,5,7,9) then  
          return ('');
      end if;  
      if IDcardlen = 15 and Substr(p_IDcard,15,1) in (2,4,6,8,0)then  
              return ('');
      end if;  
      
end getSex;

   /* (三)總結用途

主要結合某實際項目,說三點:

(1)實現15位/18位身份證號碼智能登錄
     登錄時,如果庫里的是15位,系統用18位號碼登錄,應提示相關信息,輔助完成系統登錄。
     反之,提示用戶號碼輸入不正確。


(2)自動升級庫中的身份證號碼從15位到18位
    
     這個當然不能輕易機械的升級了,不過如果有重復數據時,判斷重復數據,保留最新號碼信息絕對是個好辦法,如同時存在15位和18位,是否可以留18位就可以了?

(3)智能校驗:判斷身份證輸入,以及關聯的性別、出生年月等是否正確
  
     按公安部門發布的號碼規則校驗,當然是有效和有用的:)*/
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM