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 导出身份证号_oracle 根据身份证号计算出生日期相关推荐

  1. oracle 导出身份证号_ORACLE对身份证号码处理相关的SQL【收藏】

    /*ORACLE对身份证号码处理相关的SQL汇总 身份证号码算法及应用场景: 工作实践总结,与大家分享快乐,并请高人批评指正,努力改进: 目前我国大量存在着正在有效期的15位身份证,虽然国家在推行二代 ...

  2. oracle 导出身份证号_ORACLE对身份证号码处理相关的SQL汇总

    目前我国大量存在着正在有效期的15位身份证,虽然国家在推行二代身份证,但尚未发现强行要求全国人民更换未到期的15位身份证的官方声明或公告. 扯远了:),总之合法的15位身份证号码将在今后一段时间内继续 ...

  3. oracle 导出身份证号_oracle解析身份证号码.sql

    -- 创建一个表 drop table employee ;create table employee ( NO number(4) primary key not null  , NAME varc ...

  4. oracle手机号码检验字数_oracle 检验身份证号是否正确基本方法

    此前在文章中给出了函数和存储过程是如何判断身份证号是否是正确的,下面我详列下判断方法: 1.号码的结构 公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成.排列顺序从左至右依次为:六位数字地 ...

  5. sql server 根据身份证号计算出生日期和年龄的存储过程

    我这边有一个业务,需要客户填写身份证号,自动计算他的出生日期和年龄 在sql中,具体的存储过程实现是这样的: /******************************************** ...

  6. js中如何通过身份证号计算出生日期和年龄

    在html中有如下标签 身份证号:<input type="text" id="Gra_IDCard" onChange="IDCardChan ...

  7. 根据身份证号(18/15)计算年龄、出生日期、性别

    #region 根据身份证号计算年龄.出生日期.性别 /// <summary> /// 根据身份证获取身份证信息 /// 18位身份证 /// 0出生年月日(7~14位) /// 1性别 ...

  8. 在JS中根据身份证号计算出生日期和年龄

    1.根据身份证号计算出生日期 var identificationCardid=document.getElementById("identificationCardid").va ...

  9. mysql根据身份证号查 性别、年龄以及出生日期

    mysql根据身份证号查性别.年龄以及出生日期 博客里面还有对应的java工具类:芜湖,起飞 这个身份证号也就只针对大陆身份证号 SELECT p.id,-- 这是根据身份证号求年龄 (YEAR(NO ...

最新文章

  1. 单手也能创奇迹!独臂博士单手敲代码获奖 30 余项:感恩所有的善意
  2. 【评分】团队作业-随堂小测(同学录)
  3. Centos之压缩和解压缩命令
  4. ssh反向主动连接 及脚本加密
  5. 模式识别之Shape Context---利用Shape Context进行形状识别
  6. Shiro安全框架的使用
  7. wxWidgets:拖动一个 wxWindow
  8. linux usb声卡 submit urb,linux usb urb详解
  9. 第四节:跨域请求的解决方案和WebApi特有的处理方式
  10. tr069相关协议说明
  11. B站举办2019年度UP主颁奖:破圈、多元、跨界成全年关键词
  12. 线性表:3.链表,单链表详解与C语言实现
  13. 高岭土吸附阳离子_水分子在高岭土中吸附特性的蒙特卡罗模拟研究
  14. Class.forName(com.mysql.jdbc.driver);
  15. 【赶紧收藏】平面设计必备字体,广告设计常用字体
  16. 【视觉SLAM14讲】【汇总】
  17. html鼠标经过状态,HTML5 - 让Canvas内部元素实现鼠标移入、移出效果(Tooltip提示效果)...
  18. 解除Word的编辑保护【简单版】
  19. 踩坑:云服务器Nginx部署前端遇到http与https问题
  20. js(jquery)绑定点击事件

热门文章

  1. Matlab pdepd函数偏微分方程的求解问题
  2. python3中flask下载文件:图像.jpg
  3. 高等数学强化6:二重积分
  4. 无法启动程序 系统找不到指定的文件
  5. 将Sublime Text 设置成中文版
  6. 书单推荐|书籍是人类的良师益友
  7. 基于Wi-Fi的室内定位在美团总部的实践和应用
  8. UrlRewriter url 地址重写
  9. Sqlserver 中临时表和全局临时表
  10. Codeforces 1278 B. A and B (思维题)