PostgreSQL pgsql身份证格式校验,身份证格式提取api

身份证ID结构说明

身份证号包含的信息:

空间:6位行政区划

时间:出生日期8位(二代),6位(一代)

顺序:同地区同日期内出生人的序号

性别:奇数顺序码为男性,偶数为女性

校验码:对前17位校验求和模11的余数,余10则为X

一代身份证

长度为15位整数,由三部分组成:

6位区划 6位生日 3位序号

610204 - 541216 - 180

二代身份证

长度为18位整数,由四部分组成:

6位区划 8位生日 3位序号 1位校验码

610204 - 19541216 - 180 - 8

基本功能
  信息提取
  区划代码
  出生日期
  序列号
  性别
  校验和
形式验证
  是否合法一代证号
  是否合法二代证号
  计算校验和
拼接创建:
  升级一代证号
  创建新二代证号
  生成随机合规二代证号
COMMENT ON FUNCTION sfz_adcode(id text) IS '提取6位地区代码,输入18/15位字符身份证号,返回6位整数区划代码';
COMMENT ON FUNCTION sfz_birthday(id text) IS '提取8位出生日期,输入18/15位字符身份证号,返回出生日期,非法日期返回空';
COMMENT ON FUNCTION sfz_sequence(id text) IS '提取3位序列号,输入18/15位字符身份证号,返回3位序列号字符';
COMMENT ON FUNCTION sfz_is_male(id text) IS '输入18/15位字符身份证号,返回是否代表男性';
COMMENT ON FUNCTION sfz_is_female(id text) IS '输入18/15位字符身份证号,返回是否代表女性';
COMMENT ON FUNCTION sfz_checksum(id text) IS '提取身份证末位校验和,15位身份证号返回空';
COMMENT ON FUNCTION sfz_calculate_checksum(id text) IS '身份证号校验和,输入为17/18位身份证号,计算得到最后一位校验和';
COMMENT ON FUNCTION sfz_valid_v2(id text) IS '检查是否为合法18位二代身份证号:长度,日期,校验和。地区码暂不检查';
COMMENT ON FUNCTION sfz_valid_v1(id text) IS '检查是否为合法15位一代身份证号:长度,日期。地区码暂不检查';
COMMENT ON FUNCTION sfz_new(INTEGER,DATE,INTEGER) IS '使用地区码,生日,序列号创建18位二代身份证';
COMMENT ON FUNCTION sfz_upgrade(id text) IS '将一个合法的15位身份证升级为18位二代身份证';
COMMENT ON FUNCTION sfz_new(INTEGER,DATE,INTEGER) IS '生成一个随机的符合语法语义的身份证号';
---------------------------------
-- 身份证ID结构说明
---------------------------------
-- 身份证号包含的信息:
-- 空间:6位行政区划
-- 时间:出生日期8位(二代),6位(一代)
-- 顺序:同地区同日期内出生人的序号
-- 性别:奇数顺序码为男性,偶数为女性
-- 校验吗:对前17位校验求和模11的余数,余10则为X

-- 一代身份证
-- 长度为15位整数,由三部分组成:
-- 6位区划   6位生日  3位序号
-- 610204 - 541216 - 180

-- 二代身份证
-- 长度为18位整数,由四部分组成:
-- 6位区划    8位生日   3位序号 1位校验码
-- 610204 - 19541216 - 180 - 8

-- 基本功能
-- 信息提取:区划代码,出生日期,序列号,性别,校验和
-- 形式验证:是否合法一代证号,是否合法二代证号,计算校验和
-- 拼接创建:升级一代证号,创建新二代证号,生成随机合规二代证号
---------------------------------
---------------------------------
-- 字段解析 API
---------------------------------

字段解析 API

– 提取前6位行政区划代码

CREATE OR REPLACE FUNCTION sfz_adcode(id TEXT) RETURNS INTEGER RETURNS NULL ON NULL INPUT
AS $$ SELECT substr(id, 1, 6)::INTEGER; $$ LANGUAGE sql IMMUTABLE;
COMMENT ON FUNCTION sfz_adcode(id text) IS '提取6位地区代码,输入18/15位字符身份证号,返回6位整数区划代码';

– 提取前中间8位出生日期(一代证返回补足19前缀的完整日期)

CREATE OR REPLACE FUNCTION sfz_birthday(id TEXT) RETURNS DATE RETURNS NULL ON NULL INPUT
AS $$ BEGIN
    BEGIN
        RETURN (CASE length(id) WHEN 18 THEN substr(id, 7, 8) WHEN 15 THEN '19' || substr(id, 7, 6) END)::DATE;
    EXCEPTION
        WHEN datetime_field_overflow THEN RETURN NULL;
    END;
END; $$ LANGUAGE PlPgSQL IMMUTABLE;
COMMENT ON FUNCTION sfz_birthday(id text) IS '提取8位出生日期,输入18/15位字符身份证号,返回出生日期,非法日期返回空';

– 提取尾部3位序号

CREATE OR REPLACE FUNCTION sfz_sequence(id TEXT) RETURNS VARCHAR(3) RETURNS NULL ON NULL INPUT
AS $$ SELECT CASE length(id) WHEN 18 THEN substr(id, 15, 3) WHEN 15 THEN substr(id,
PostgreSQL 中,可以使用表分区技术实现数据分区。要使用身份证前6位来建立分区,可以按照以下步骤进行操作: 1. 创建一个父表,用于存储所有分区的元数据信息: ```sql CREATE TABLE partition_parent ( id SERIAL PRIMARY KEY, partition_name TEXT NOT NULL, partition_start TEXT NOT NULL, partition_end TEXT NOT NULL ); ``` 2. 创建一个函数,用于根据身份证前6位来计算分区名称: ```sql CREATE OR REPLACE FUNCTION partition_name_fn(id_num TEXT) RETURNS TEXT AS $$ DECLARE prefix TEXT; BEGIN prefix := SUBSTRING(id_num from 1 for 6); RETURN 'partition_' || prefix; END; $$ LANGUAGE plpgsql; ``` 3. 创建一个触发器,用于在插入数据时根据身份证前6位来将数据插入到对应的分区中: ```sql CREATE OR REPLACE FUNCTION partition_insert_fn() RETURNS TRIGGER AS $$ DECLARE partition_name TEXT; BEGIN partition_name := partition_name_fn(NEW.id_num); IF NOT EXISTS(SELECT relname FROM pg_class WHERE relname = partition_name) THEN EXECUTE 'CREATE TABLE ' || partition_name || ' (LIKE ' || TG_TABLE_NAME || ' INCLUDING ALL)'; EXECUTE 'ALTER TABLE ' || partition_name || ' ADD CONSTRAINT ' || partition_name || '_pk PRIMARY KEY (id)'; EXECUTE 'ALTER TABLE ' || partition_name || ' ADD CONSTRAINT ' || partition_name || '_check CHECK (id_num >= ''' || partition_start || ''' AND id_num < ''' || partition_end || ''')'; EXECUTE 'ALTER TABLE ' || partition_name || ' INHERIT ' || TG_TABLE_NAME; INSERT INTO partition_parent (partition_name, partition_start, partition_end) VALUES (partition_name, partition_start, partition_end); END IF; EXECUTE 'INSERT INTO ' || partition_name || ' SELECT ($1).*' USING NEW; RETURN NULL; END; $$ LANGUAGE plpgsql; CREATE TRIGGER partition_insert_trg BEFORE INSERT ON my_table FOR EACH ROW EXECUTE FUNCTION partition_insert_fn(); ``` 在上面的代码中,我们假设要对名为 my_table 的表进行分区,其中包含一个名为 id_num 的列,用于存储身份证号码。触发器会在插入数据时根据身份证前6位来计算分区名称,并将数据插入到对应的分区中。同时,如果该分区还不存在,则会动态创建该分区,并将元数据信息插入到 partition_parent 表中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值