使用mysql的儲存過程實現身份證校驗

2021-10-11 02:12:44 字數 3947 閱讀 9478

校驗規則:

1、身份證號碼前17位數分別乘以不同的係數。從第一位到第十七位的係數分別為:7、9、10、5、8、4、2、1、6、3、7、9、10、5、8、4、2 ;

2、將這17位數字和係數相乘的結果相加;用加出來和除以11,看餘數是多少;

3、餘數只可能有0、1、2、3、4、5、6、7、8、9、10這11個數字。其分別對應的最後一位身份證的號碼為1、0、x、9、8、7、6、5、4、3、2;

4、通過上面得知如果餘數是2,就會在身份證的第18位數字上出現羅馬數字的ⅹ;如果餘數是10,身份證的最後一位號碼就是2

不多介紹,直接上**:

create definer=`root`@`%` function `validate_idcard`(`p_idcard` varchar(18)) returns varchar(255) charset utf8

begin

#校驗身份證號是否正確 15位身份證校驗存在問題

#返回結果 error-錯誤 success-正確

declare v_regstr varchar ( 2000 );#正則

declare v_sum int (11);#求和

declare v_mod int (11);#求餘

declare v_checkcode char (11) default '10x98765432';#校驗碼表

declare v_checkbit char (1);#校驗碼

#區域**,驗證身份證號是否在所在區域

declare v_areacode varchar (2000) default '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,';

declare v_idcard17 varchar(20);#17位身份證號

#身份證前17位每位加權因子;

case length (p_idcard)

when 15 then

if instr(v_areacode,substr(p_idcard,1,2)) = 0 then

return "error";

end if;

if(substr(p_idcard,7,4))%400 = 0 then

set v_regstr := '^[1-9][0-9][0-9]((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]$';

else set v_regstr := '^[1-9][0-9][0-9]((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]$';

if (p_idcard regexp v_regstr = 1 ) then

#15位身份證轉17位

set v_idcard17:= concat(substring(p_idcard,1,6) , substring(str_to_date(substring(p_idcard,7,6),'%y%m%d'),1,4) , substring(p_idcard,9));

#開始計算

set v_sum:= ((substr(v_idcard17,1,1)+substr(v_idcard17,11,1)))*7+(substr(v_idcard17,2,1)+substr(v_idcard17,12,1))*9+(substr(v_idcard17,3,1)+substr(v_idcard17,13,1))*10+(substr(v_idcard17,4,1)+substr(v_idcard17,14,1))*5+(substr(v_idcard17,5,1)+substr(v_idcard17,15,1))*8+(substr(v_idcard17,6,1)+substr(v_idcard17,16,1))*4+(substr(v_idcard17,7,1)+substr(v_idcard17,17,1))*2+(substr(v_idcard17,8,1))*1+(substr(v_idcard17,9,1))*6+(substr(v_idcard17,10,1))*3;

set v_mod := v_sum%11;

set v_checkbit := substr(v_checkcode, v_mod + 1,1);

set v_idcard17 := concat(v_idcard17,v_checkbit);

if v_checkbit = upper(substr( v_idcard17, 18, 1)) then

return "success";

else return "error";

end if;

else return "error";

end if;

end if;

when 18 then

if instr(v_areacode,substr(p_idcard,1,2)) = 0 then

return "error";

end if;

#存在if (substr(p_idcard,7,4)) % 400 = 0 then

set v_regstr := '^[1-9][0-9](19|20)[0-9]((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][0-9xx]$';

else

set v_regstr := '^[1-9][0-9](19|20)[0-9]((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][0-9xx]$';

end if;

#校驗if (`p_idcard` regexp v_regstr = 1 ) then

set v_sum:= ((substr(p_idcard,1,1)+substr(p_idcard,11,1)))*7+(substr(p_idcard,2,1)+substr(p_idcard,12,1))*9+(substr(p_idcard,3,1)+substr(p_idcard,13,1))*10+(substr(p_idcard,4,1)+substr(p_idcard,14,1))*5+(substr(p_idcard,5,1)+substr(p_idcard,15,1))*8+(substr(p_idcard,6,1)+substr(p_idcard,16,1))*4+(substr(p_idcard,7,1)+substr(p_idcard,17,1))*2+(substr(p_idcard,8,1))*1+(substr(p_idcard,9,1))*6+(substr(p_idcard,10,1))*3;

set v_mod := v_sum%11;

set v_checkbit := substr(v_checkcode, v_mod + 1,1);

if v_checkbit = upper(substr( p_idcard, 18, 1 ) ) then

return "success";

else return "error";

end if;

end if;

return "error";

end case;

return 0;

end

15位身份證號碼無法校驗,可在傳入15位時直接返回成功或失敗,上述**未做處理

儲存過程 MySQL儲存過程的使用總結

案例所涉及到的表如下 create table t goods g id varchar 20 not null comment 商品編號 g name varchar 30 default null comment 商品名稱 g price float default null comment 商...

MySQL 使用儲存過程實現留存率

delimiter use resourcemanage dev drop procedure if exists stat remain player create definer root localhost procedure stat remain player begin 今天的日期 de...

mysql儲存登入 MYSQL儲存過程實現使用者登入

create definer root function uc session login re son json,srvjson json returnsjson language sqlnotdeterministiccontainssql sql security definer commen...