Oracle 校验统一社会信用代码函数

一、统一社会信用代码编码规则

统一代码由十八位的阿拉伯数字或大写英文字母(不使用I、O、Z、S、V)组成,包括第1位登记管理
部门代码、第2位机构类别代码、第3位第8位登记管理机关行政区划码、第9位第17位主体标识
码(组织机构代码)、第18位校验码五个部分。

代码及说明

第1位:登记管理部门代码

登记管理部门代码使用阿拉伯数字或大写英文字母表示,登记管理部门代码标识如下表:
在这里插入图片描述

第2位:机构类别代码

机构类别代码使用阿拉伯数字表示,如下表:
在这里插入图片描述

第3位~第8位:登记管理机关行政区划码

登记管理机关行政区划码使用阿拉伯数字表示

第9位~第17位:主体标识码(组织机构代码)

主体标识码使用阿拉伯数字或大写英文字母表示

第18位:校验码

校验码使用阿拉伯数字或大写英文字母表示,校验码按下列公式计算:
在这里插入图片描述

MOD(n,m)———整数求余函数,例如:函数 MOD(31,31)的值为0;
i ———代码字符从左到右的位置序号;
Ci ———第i位置上的代码字符的值,'0123456789ABCDEFGHJKLMNPQRTUWXY’字符对应的值
对应数字0-30;
C18 ———校验码;
Wi ———第i位上的加权因子,加权因子见下表。
在这里插入图片描述
在这里插入图片描述

当 MOD函数值为1(即C18=30)时,校验码应用符号 Y 表示;当 MOD函数值为0(即C18=31)时,校验码用0表示。

二、校验函数编码

CREATE OR REPLACE FUNCTION FN_UNISCID_CHECK(in_uniscid VARCHAR2)
  RETURN VARCHAR2 IS
  /*
    用途:校验统一社会信用代码
    创建人:gangma2
    创建时间:2021-12-03
  */
  --统一社会信用代码
  v_uniscid VARCHAR2(100);
  --统一社会信用代码长度
  v_length  NUMBER;
  --正则表达式
  v_regstr  VARCHAR2(2000);
  --ci*wi求和
  v_sum     NUMBER := 0;
  --检验位对应位置
  v_jy      VARCHAR2(1);
  /*统一社会信用代码字符串中字符对应V_CI位置数-1,如统一社会信用代码中91350100M0000100Y4,
  M对应的数值为instr( '0123456789ABCDEFGHJKLMNPQRTUWXY','M',1,1)-1*/
  v_ci CHAR(35) := '0123456789ABCDEFGHJKLMNPQRTUWXY';
  --定义数字型类型数组及变量
  TYPE v_number IS TABLE OF NUMBER;
  v_wi v_number := v_number(1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28);
  --区划省份代码
  v_areacode VARCHAR2(2000) := '11,12,13,14,15,21,22,23,31,32,33,34,35,36,37,41,42,43,44,45,46,50,51,52,53,54,61,62,63,64,65,71,81,82,91,';

BEGIN

  --1、去掉'-'、空格、小写转换为大写字符
  v_uniscid := UPPER(RTRIM(LTRIM(REPLACE(in_uniscid, '-', ''))));

  --2、判断是否为空
  IF (v_uniscid IS NULL) THEN
    BEGIN
      RETURN '统一社会信用代码为空!';
    END;
  END IF;

  --3、判断长度
  v_length := LENGTHB(v_uniscid);
  IF v_length <> 18 THEN
    RETURN '统一社会信用代码长度错误!';
  END IF;

  --4、省份代码
  IF INSTRB(v_areacode, SUBSTR(v_uniscid, 3, 2) || ',') = 0 THEN
    RETURN '统一社会信用代码省份代码错误!';
  END IF;

  --5、验证格式:验证统一社会信用代码是由数字和大写字母组及非法字符
  v_regstr := '^[159Y][1239][1-9][0-9]{5}[0-9A-Z]{10}$';

  IF NOT REGEXP_LIKE(v_uniscid, v_regstr) THEN
    RETURN '统一社会信用代码格式错误!';
  END IF;

  --6、v_uniscid的字符数值分别乘于该位的加权因子,然后求和,计算出校验码
  FOR i IN 1 .. (v_length - 1) LOOP
    v_sum := v_sum +
             (INSTR(v_ci, SUBSTR(v_uniscid, I, 1), 1, 1) - 1) * v_wi(i);
  END LOOP;

  /* 计算校验码在V_CI中位置*/
  v_jy := 31 - MOD(v_sum, 31);
  IF (v_jy = 31) THEN
    v_jy := 0;
  END IF;

  IF (SUBSTR(v_ci, v_jy + 1, 1) <> SUBSTR(v_uniscid, -1)) THEN
    RETURN '统一社会信用代码校验位错误';
  ELSE
    RETURN '校验通过!';
  END IF;
EXCEPTION
  WHEN OTHERS THEN
    RETURN '校验程序异常!';
END FN_UNISCID_CHECK;

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是一个 Oracle 营业执照代码校验函数的示例: ```sql CREATE OR REPLACE FUNCTION check_license_code(p_license_code IN VARCHAR2) RETURN VARCHAR2 IS v_license_code VARCHAR2(15) := UPPER(p_license_code); v_check_code CHAR(1); v_weight_array CONSTANT VARCHAR2(10) := '123456789ABCDEFGHJKLMNPQRTUWXY'; v_weight_num_array CONSTANT VARCHAR2(10) := '31791065432'; BEGIN -- 校验长度和字符合法性 IF LENGTH(v_license_code) <> 15 OR REGEXP_LIKE(v_license_code, '[^0-9A-Z]') THEN RETURN 'INVALID_LICENSE_CODE'; END IF; -- 计算校验码 v_check_code := v_weight_array(MOD(SUM(DECODE(SUBSTR(v_license_code, LEVEL, 1), v_weight_array, INSTR(v_weight_array, SUBSTR(v_license_code, LEVEL, 1)), NULL) * TO_NUMBER(SUBSTR(v_weight_num_array, LEVEL, 1))), 31) + 1); -- 检查校验码 IF SUBSTR(v_license_code, 15, 1) <> v_check_code THEN RETURN 'INVALID_CHECK_CODE'; ELSE RETURN 'VALID_LICENSE_CODE'; END IF; END; / ``` 该函数接收一个营业执照代码作为参数,返回一个字符串,表示校验结果。如果营业执照代码不符合规则,则返回 "INVALID_LICENSE_CODE",如果校验码不正确,则返回 "INVALID_CHECK_CODE",否则返回 "VALID_LICENSE_CODE"。使用该函数时,只需要传入营业执照代码即可。例如: ```sql SELECT check_license_code('123456789012345') FROM DUAL; -- 返回 'INVALID_LICENSE_CODE' SELECT check_license_code('1234567890123456') FROM DUAL; -- 返回 'INVALID_LICENSE_CODE' SELECT check_license_code('1234567890123456A') FROM DUAL; -- 返回 'VALID_LICENSE_CODE' SELECT check_license_code('1234567890123456B') FROM DUAL; -- 返回 'INVALID_CHECK_CODE' ``` 注意,在实际应用中,可能需要根据具体要求对该函数进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值