oracle 根据身份证号计算出生日期
1.情景展示
如何根据身份证号推算出出生日期?
2.解决方案
--根据身份证号计算出生日期
SELECT DECODE(LENGTH(ID_CARD),
18,
SUBSTR(ID_CARD, 7, 8),
15,
'19' || SUBSTR(ID_CARD, 7, 6)) 出生日期
FROM VIRTUAL_CARD
WHERE LENGTH(ID_CARD) = 18
OR LENGTH(ID_CARD) = 15

3.拓展
根据身份证号,截取出生日期后,更新到该表的birthday(日期类型)字段
第一步:一个SQL搞定
UPDATE VIRTUAL_CARD
SET BIRTHDAY = TO_DATE(DECODE(LENGTH(ID_CARD),
18,
SUBSTR(ID_CARD, 7, 8),
15,
'19' || SUBSTR(ID_CARD, 7, 6)),
'yyyymmdd')
WHERE REMARK = '3';
正常情况下,它会执行没有问题。(没有报错的不用再往下看了)
但是,现实往往不按我们想象的路子走。

这个错误的意思是:无效的月份,再直白点是:月份错误,换句话说就是:本来月份有01-12个月,但是按照身份证截取的出生月份超出了这个范围,所以在转换日期的时候报错。
第二步:删除无效的月份所在行数据
DELETE FROM VIRTUAL_CARD
WHERE ID_CARD IN (SELECT ID_CARD
FROM (SELECT DECODE(LENGTH(ID_CARD),
18,
SUBSTR(ID_CARD, 11, 2),
15,
SUBSTR(ID_CARD, 9, 2)) MON,
ID_CARD
FROM VIRTUAL_CARD
WHERE REMARK = '3')
WHERE MON NOT IN ('01',
'02',
'03',
'04',
'05',
'06',
'07',
'08',
'09',
'10',
'11',
'12'))
in()函数里,查询出来的是脏数据,我选择删掉。
再次执行第一步的代码,还是报这个错误。
既然月份存在的脏数据已经删除,那么是不是日期出了问题?即:天数超出了01-31天,这个范围
第三步:删除无效的天数
DELETE FROM VIRTUAL_CARD
WHERE ID_CARD IN (SELECT ID_CARD
FROM (SELECT /*DISTINCT*/
DECODE(LENGTH(ID_CARD),
18,
SUBSTR(ID_CARD, 13, 2),
15,
SUBSTR(ID_CARD, 11, 2)) DA,
ID_CARD
FROM VIRTUAL_CARD
WHERE REMARK = '3')
WHERE DA != 01
AND DA != 02
AND DA != 03
AND DA != 04
AND DA != 05
AND DA != 06
AND DA != 07
AND DA != 08
AND DA != 09
AND DA != 10
AND DA != 11
AND DA != 12
AND DA != 13
AND DA != 14
AND DA != 15
AND DA != 16
AND DA != 17
AND DA != 18
AND DA != 19
AND DA != 20
AND DA != 21
AND DA != 22
AND DA != 23
AND DA != 24
AND DA != 25
AND DA != 26
AND DA != 27
AND DA != 28
AND DA != 29
AND DA != 30
AND DA != 31)
说明:既可以用in()函数,也可以使用!=,in()方便一些,另外,oracle中的整数类数值型字符串,可以不加""。
果不其然,日期也有脏数据,再次删掉,执行第一步的代码,还是报错。
思考:既然日期也搞定了,还有哪会有问题?
首先,闰年有366天,这说明闰年的2月份有29天,平年有365天,2月份对应28天。
其次,1,3,5,7,8,10,12,这7个月有31天,4,6,9,11,这4个月有30天。
to_date()函数,会对其进行严格校验,只有日期无效,就不予转换。


2019年是平年,2月只有28天,当我设置成29天时,就会报月份无效。
第四步:删除假闰年数据
DELETE FROM VIRTUAL_CARD
WHERE ID_CARD IN (SELECT ID_CARD
FROM (SELECT DECODE(LENGTH(ID_CARD),
18,
SUBSTR(ID_CARD, 7, 4),
15,
'19' || SUBSTR(ID_CARD, 7, 2)) YEA,
DECODE(LENGTH(ID_CARD),
18,
SUBSTR(ID_CARD, 11, 2),
15,
SUBSTR(ID_CARD, 9, 2)) MON,
DECODE(LENGTH(ID_CARD),
18,
SUBSTR(ID_CARD, 13, 2),
15,
SUBSTR(ID_CARD, 11, 2)) DA,
ID_CARD
FROM VIRTUAL_CARD
WHERE REMARK = '3')
WHERE MON = '02'
AND DA > 28 /*2月份超过28天*/
AND MOD(YEA, 4) != 0) /*余数不为0*/
说明:闰年能够被4整除,2月份为29天,反之,平年超过28天的都是脏数据。
第五步:删除4,6,9,11月超过30天的数据
DELETE FROM VIRTUAL_CARD
WHERE ID_CARD IN
(SELECT ID_CARD
FROM (SELECT DECODE(LENGTH(ID_CARD),
18,
SUBSTR(ID_CARD, 11, 2),
15,
SUBSTR(ID_CARD, 9, 2)) MON,
DECODE(LENGTH(ID_CARD),
18,
SUBSTR(ID_CARD, 13, 2),
15,
SUBSTR(ID_CARD, 11, 2)) DA,
ID_CARD
FROM VIRTUAL_CARD
WHERE REMARK = '3')
WHERE (MON IN ('04', '06', '09', '11') AND DA > 30))
再次执行第一步的更新代码,成功更新完毕。

为了以防万一,先做检验,再提交数据。(在当前窗口执行查询SQL)

没有毛病,提交数据,大功告成。
另外,看到这里,我们对身份证的有效性的校验就又多了一种方式。
通过截取身份证号的出生日期,利用to_date()函数进行日期转换,转换失败的话,说明该身份证号绝壁有问题。
还有一种方式是:系统游标批量更新法
使用游标循环单行更新,捕获异常,继续执行下一条数据更新,直至更新完毕。
这样,最后birthday字段没有更新的行数据(字段为空),就是脏数据。
4.拓展2
保留身份证号的前4位和后4位,中间部位隐藏。
SELECT SUBSTR(ID_CARD, 1, 4) ||/*截取前4位*/
DECODE(LENGTH(ID_CARD), 18, '**********', 15, '*******') ||/*中间用*号代替*/
SUBSTR(ID_CARD, -4) 身份证号/*截取后4位*/
FROM VIRTUAL_CARD
WHERE REMARK = 3
ORDER BY ADDRESS
oracle 根据身份证号计算出生日期的更多相关文章
- js中如何通过身份证号计算出生日期和年龄
在html中有如下标签 身份证号:<input type="text" id="Gra_IDCard" onChange="IDCardChan ...
- sql server 根据身份证号计算出生日期和年龄的存储过程
我这边有一个业务,需要客户填写身份证号,自动计算他的出生日期和年龄 在sql中,具体的存储过程实现是这样的: /******************************************** ...
- 教你一招:根据身份证号计算出生年月和年龄 text函数和mid函数混用 datedif函数和today函数混用
在电子表格Excel中,使用text函数和mid函数混用,根据身份证号计算出生年月: =text(mid(A2,,),"0!/00!/00") #0!/00!/00 为日期的格式# ...
- Javascript 身份证号获得出生日期、获得性别、检查身份证号码
//---------------------------------------------------------- // 功能:根据身份证号获得出生日期 // 参数:身份证号 psidno // ...
- SQL语句通过身份证号计算年龄
SQL语句通过身份证号计算年龄 1.截取身份证号上的出生日期 身份证一般为18位数和15位数 18位数身份证的第7-10位数是出生年份,第11-14位数是出生月日,所以18位身份证的年龄计算如下 su ...
- JavaScript 通过身份证号获取出生日期、年龄、性别 、籍贯
JavaScript 通过身份证号获取出生日期.年龄.性别 .籍贯(很全) 效果图: 示例代码: //由于没有写外部JS,所以代码比较长!!! <!DOCTYPE html PUBLIC &qu ...
- python 根据生日计算年龄 sqlalchemy根据身份证号计算生日 性别
import datetime '): birth_d = datetime.datetime.strptime(birth_s, "%Y%m%d") today_d = date ...
- EXCEL计算根据当前时间和身份证号计算准确年龄
假设身份证号在A2单元格 =IF(MONTH(NOW())<MONTH(DATE(MID(A2,7,4),MID(A2,11,2),MID(A2,13,2))),INT(YEAR(NOW())- ...
- oracle根据身份证号码 计算年龄、性别
一.Oracle根据身份证判断性别: 女生身份证: 431382198103246985 男生身份证: 150921197208173492 SQL语句如下: select decode(mod ...
随机推荐
- Python网络编程、爬虫之requests模块使用
一.python操作网络,也就是打开一个网站,或者请求一个http接口,使用urllib模块. urllib模块是一个标准模块,直接import urllib即可,在python3里面只有urllib ...
- Java自学-异常处理 异常分类
Java 中异常的分类 异常分类: 可查异常,运行时异常和错误3种 其中,运行时异常和错误又叫非可查异常 步骤 1 : 可查异常 可查异常: CheckedException 可查异常即必须进行处理的 ...
- Serverless
一.介绍 是指依赖于第三方应用程序或服务来管理服务器端逻辑的应用程序. 此类应用程序是基于云的数据库(如Google Firebase)或身份验证服务. 无服务器也意味着开发为事件触发的代码,并且在无 ...
- OpenGl函数库
[OpenGL核心函数库] glAccum操作累加缓冲区glAddSwapHintRectWIN定义一组被SwapBuffers拷贝的三角形glAlphaFunc允许设置alpha检测功能glAreT ...
- 【转载】Asp.Net生成图片验证码工具类
在Asp.Net应用程序中,很多时候登陆页面以及其他安全重要操作的页面需要输入验证码,本文提供一个生成验证码图片的工具类,该工具类通过随机数生成验证码文本后,再通过C#中的图片处理类位图类,字体类,一 ...
- odex vdex art区别
一.vdexpackage 直接转化的 可执行二进制码 文件:1.第一次开机就会生成在/system/app/<packagename>/oat/下:2.在系统运行过程中,虚拟机将其 从 ...
- scala快速入门之文档注释
scala快速入门之文档注释 1.在项目栏的目录树中找到该源码,右击点击Show in Explorer, 即可找到该源码的本地路径,在路径中输入cmd 2.执行scaladoc -d 生成文档注释 ...
- JVM 运行时数据区:程序计数器、Java 虚拟机栈和本地方法栈,方法区、堆以及直接内存
Java 虚拟机可以看作一台抽象的计算机,如同真实的计算机,它也有自己的指令集和运行时内存区域. Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存(运行时内存区域)划分为若干个不同的数 ...
- Prometheus(四):Prometheus+Alertmanager 配置邮件报警
此处默认已安装Prometheus服务,服务地址:192.168.56.200 一.安装Alertmanager 此处采用源码编译的方式安装.首先下载alertmanager的软件包,下载地址:ht ...
- find 和grep的区别
find(以文件属性为查找条件) grep(以文件内容为查找条件) grep works /usr/local/apache/htdocs/index.html 1.将/etc/passwd,有出现 ...