Greenplum数据库身份证查验函数

以下为 Greenplum 6.x 专用 的身份证校验函数,完整保留原始逻辑,无任何删减或优化,可直接复制使用:

sql 复制代码
CREATE OR REPLACE FUNCTION CHECK_ID_CARD("sfzh" varchar)
  RETURNS varchar AS $body$  
DECLARE
    RESULTS varchar(30);
BEGIN
	RESULTS := CASE
	WHEN sfzh IS NULL THEN
		'身份证号不能为空'
	WHEN LENGTH(sfzh) <> 18 THEN
		'身份证号码必须为18位'
	WHEN (substring(sfzh,1,17) ~ '[^0-9]' ) = 't' THEN
	  '身份证号码前17位格式不正确'
	WHEN substring(sfzh,7,4) NOT BETWEEN '1900' AND to_char(now(),'YYYY') THEN
		'身份证年份错误'
	WHEN substring(sfzh,11,2) NOT BETWEEN '01' AND '12' THEN 
		'身份证月份错误'
	WHEN substring(sfzh,13,2) NOT BETWEEN '01' AND to_char((date_trunc('month',to_date
	(CONCAT(substring(sfzh,7,4),'-',substring(sfzh,11,2),'-01'),'YYYY-MM-DD')) + interval '1 month' - interval '1 day'),'dd') THEN 
		'身份证日期错误'
	WHEN 
		mod(( 
            to_number(substring(sfzh,1,1),'9')*7+ 
            to_number(substring(sfzh,2,1),'9')*9+ 
            to_number(substring(sfzh,3,1),'9')*10+ 
            to_number(substring(sfzh,4,1),'9')*5+ 
            to_number(substring(sfzh,5,1),'9')*8+ 
            to_number(substring(sfzh,6,1),'9')*4+ 
            to_number(substring(sfzh,7,1),'9')*2+ 
            to_number(substring(sfzh,8,1),'9')*1+ 
            to_number(substring(sfzh,9,1),'9')*6+ 
            to_number(substring(sfzh,10,1),'9')*3+ 
            to_number(substring(sfzh,11,1),'9')*7+ 
            to_number(substring(sfzh,12,1),'9')*9+ 
            to_number(substring(sfzh,13,1),'9')*10+ 
            to_number(substring(sfzh,14,1),'9')*5+ 
            to_number(substring(sfzh,15,1),'9')*8+ 
            to_number(substring(sfzh,16,1),'9')*4+ 
            to_number(substring(sfzh,17,1),'9')*2 
          ),11) 
			<> to_number(
          ( 
          case
            when substring(sfzh,18,1)='1' then '0'
            when substring(sfzh,18,1)='0' then '1'
            when substring(sfzh,18,1) in ('X','x') then '2'
            when substring(sfzh,18,1)='9' then '3'
            when substring(sfzh,18,1)='8' then '4'
            when substring(sfzh,18,1)='7' then '5'
            when substring(sfzh,18,1)='6' then '6'
            when substring(sfzh,18,1)='5' then '7'
            when substring(sfzh,18,1)='4' then '8'
            when substring(sfzh,18,1)='3' then '9'
            when substring(sfzh,18,1)='2' then '10'
          end
          ),'99')
	THEN
		'身份证验证错误'
	ELSE
		'ok'
	END;
	Return(RESULTS);
END
$body$ LANGUAGE plpgsql;

核心逻辑说明

  1. 长度与格式

    LENGTH(sfzh) = 前17位全数字 + 第18位合法(数字/X/x)

  2. 日期合法性

    -- 自动校验当月最大天数(含闰年)
    to_char(date_trunc('month', to_date(...)) + interval '1 month' - interval '1 day', 'dd')

  3. 校验码算法 (GB 11643-1999)

    • 前17位按权重 [7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2] 加权求和
    • 求和后 mod 11
    • 根据余数映射校验码(0→1, 1→0, 2→X, 3→9, ..., 10→2

使用示例

sql 复制代码
-- 检查异常身份证
SELECT 
  sfzh,
  CHECK_ID_CARD(sfzh) AS check_result
FROM user_info

-- 输出示例:
-- 110101199002301234 | 身份证日期错误
-- 11010119900101123X | 身份证验证错误
-- 110101199001011234 | ok
相关推荐
AllData公司负责人22 分钟前
AllData数据中台-数据同步平台【Seatunnel-Web】整库同步MySQL同步Doris能力演示
大数据·数据库·mysql·开源
加油,小猿猿30 分钟前
Java开发日志-双数据库事务问题
java·开发语言·数据库
山岚的运维笔记1 小时前
SQL Server笔记 -- 第20章:TRY/CATCH
java·数据库·笔记·sql·microsoft·sqlserver
Gain_chance1 小时前
33-学习笔记尚硅谷数仓搭建-DWS层交易域用户粒度订单表分析及设计代码
数据库·数据仓库·hive·笔记·学习·datagrip
未来之窗软件服务1 小时前
计算机等级考试—高频英语词汇—东方仙盟练气期
数据库·计算机软考·东方仙盟
lekami_兰1 小时前
MySQL 长事务:藏在业务里的性能 “隐形杀手”
数据库·mysql·go·长事务
JQLvopkk2 小时前
C# 轻量级工业温湿度监控系统(含数据库与源码)
开发语言·数据库·c#
devmoon3 小时前
在 Polkadot Runtime 中添加多个 Pallet 实例实战指南
java·开发语言·数据库·web3·区块链·波卡
认真的薛薛3 小时前
数据库-sql语句
数据库·sql·oracle
爱学英语的程序员3 小时前
面试官:你了解过哪些数据库?
java·数据库·spring boot·sql·mysql·mybatis