MySQL·身份证校验

本文节选自《Netkiller Architect 手札》

4.17. 数据检查

4.17.1. 身份证校验

该函数能够检查身份证号码是否正确

CREATE DEFINER=`neo`@`%` FUNCTION `check_id_number`(`idnumber` CHAR(18))
	RETURNS enum('true','false')
	LANGUAGE SQL
	NOT DETERMINISTIC
	NO SQL
	SQL SECURITY DEFINER
	COMMENT ''
BEGIN
DECLARE status ENUM('true','false') default 'false';
DECLARE verify CHAR(1);
DECLARE sigma INT;
DECLARE remainder INT;

IF length(idnumber) = 18 THEN
	set sigma = cast(substring(idnumber,1,1) as UNSIGNED) * 7
		+cast(substring(idnumber,2,1) as UNSIGNED) * 9
		+cast(substring(idnumber,3,1) as UNSIGNED) * 10
		+cast(substring(idnumber,4,1) as UNSIGNED) * 5
		+cast(substring(idnumber,5,1) as UNSIGNED) * 8
		+cast(substring(idnumber,6,1) as UNSIGNED) * 4
		+cast(substring(idnumber,7,1) as UNSIGNED) * 2
		+cast(substring(idnumber,8,1) as UNSIGNED) * 1
		+cast(substring(idnumber,9,1) as UNSIGNED) * 6
		+cast(substring(idnumber,10,1) as UNSIGNED) * 3
		+cast(substring(idnumber,11,1) as UNSIGNED) * 7
		+cast(substring(idnumber,12,1) as UNSIGNED) * 9
		+cast(substring(idnumber,13,1) as UNSIGNED) * 10
		+cast(substring(idnumber,14,1) as UNSIGNED) * 5
		+cast(substring(idnumber,15,1) as UNSIGNED) * 8
		+cast(substring(idnumber,16,1) as UNSIGNED) * 4
		+cast(substring(idnumber,17,1) as UNSIGNED) * 2;
	set remainder = MOD(sigma,11);
	set verify = (case remainder
		when 0 then '1' when 1 then '0' when 2 then 'X' when 3 then '9'
		when 4 then '8' when 5 then '7' when 6 then '6' when 7 then '5'
		when 8 then '4' when 9 then '3' when 10 then '2' else '/' end
	);

END IF;

IF right(idnumber,1) = verify THEN
	set status = 'true';
END IF;

RETURN status;

END			

首先我们使用正确身份证号码进行测试,返回true

			mysql> select check_id_number('330702198003090915');
+---------------------------------------+
| check_id_number('330702198003090915') |
+---------------------------------------+
| true                                  |
+---------------------------------------+
1 row in set (0.01 sec)			

长度不符合18位直接返回false.

			mysql> select check_id_number('33070219800309');
+-----------------------------------+
| check_id_number('33070219800309') |
+-----------------------------------+
| false                             |
+-----------------------------------+
1 row in set (0.00 sec)	

mysql> select check_id_number('33070219800309091457889');
+--------------------------------------------+
| check_id_number('33070219800309091457889') |
+--------------------------------------------+
| false                                      |
+--------------------------------------------+
1 row in set, 1 warning (0.00 sec)			

随便改译为数,校验失败返回 false

			mysql> select check_id_number('330702198003090914');
+---------------------------------------+
| check_id_number('330702198003090914') |
+---------------------------------------+
| false                                 |
+---------------------------------------+
1 row in set (0.00 sec)					

原文发布于微信公众号 - Netkiller(netkiller-ebook)

原文发表时间:2016-10-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏测试开发架构之路

SQL语句之奇形怪状的冷门函数

lag() over() SELECT C.*,LAG(C.column,1) OVER(ORDER BY C.column) FROM Table C; 第...

2743
来自专栏行者常至

pgsql编写触发器

600
来自专栏跟着阿笨一起玩NET

(3)合并列值与分拆列值

在SQL中分拆列值和合并列值老生常谈了,从网上搜刮了一下并记录下来,以便不时之需 :)

691
来自专栏跟着阿笨一起玩NET

通过存储过程进行分页查询的SQL示例

1061
来自专栏AhDung

【SQL】统计所有表的行数

原理:遍历所有用户表,用sp_spaceused过程分别获取每张表的行数并写入临时表,最后返回临时表

1142
来自专栏杨建荣的学习笔记

使用copy命令解决LONG类型的困扰(r2第24天)

在oracle的数据类型中,long类型算是一个比较另类的典型,早就不建议使用了,但是在数据字典里还是能看到long 类型的影子。 如果在一些工作中碰到long...

2946
来自专栏乐沙弥的世界

SQL基础--> 约束(CONSTRAINT)

约束是表、列级的强制规定、是防止那些无效或有问题的数据输入到表中。当对该表进行DML

642
来自专栏java系列博客

关于ORACLE merge into 的两个常见错误

9813
来自专栏散尽浮华

mysql操作命令梳理(1)-索引

1、创建索引 索引的创建可以在CREATE TABLE语句中进行,也可以单独用CREATE INDEX或ALTER TABLE来给表增加索引。以下命令语句分别展...

2006
来自专栏测试开发架构之路

分分钟搞懂union与union all

SQL UNION 操作符 UNION 操作符用于合并两个或多个 SELECT 语句的结果集。 请注意,UNION 内部的 SELECT 语句必须拥有相同数量的...

3349

扫码关注云+社区