校验全国组织机构代码编制( GB 11714-1997)

校验全国组织机构代码编制( GB 11714-1997) Oracle PL/SQL 如下

create or replace function fn_check_org(p_code varchar2) return varchar2 is

  --校验全国组织机构代码编制( GB 11714-1997)

  --返回值: 1-正确 2-格式非法 3-校验位错误 4-计算时出现异常

  /*
  组织机构代码是每一个机关、社会团体、企事业单位在全国范围内唯一的、始终不变的法定代码标识。
  最新使用的组织机构代码在1997年颁布实施,由8位数字(或大写拉丁字母)本体代码和1位数字(或大写拉丁字母)校验码组成。
  本体代码采用系列(即分区段)顺序编码方法。校验码按下列公式计算:
  C9 = 11 - MOD ( ∑Ci * Wi ,11) … (2)
  i=1
  其中:MOD —— 表示求余函数;
  i  —— 表示代码字符从左到右位置序号;
  Ci —— 表示第i位置上的代码字符的值,采用附录A“代码字符集”所列字符;
  C9 —— 表示校验码;
  Wi —— 表示第i位置上的加权因子,其数值如下表:
  i  1 2 3 4  5 6 7 8
  Wi 3 7 9 10 5 8 4 2
  当MOD函数值为1(即 C9 = 10)时,校验码用字母X表示。
  */

  v_result varchar2(100);
  i        number(2) := 0;
  len      number(2) := 0;
  sigma    number(4) := 0;
  type it is table of int;

  --加权因子
  a            it := it(3, 7, 9, 10, 5, 8, 4, 2);
  v_org_code   varchar2(100);
  v_right_code varchar2(100);

begin

  if not regexp_like(p_code, '^[0-9a-zA-Z]{8}-[0-9X]{1}$') then
    v_result := '2';
    --dbms_output.put_line('格式非法');
    return v_result;
  end if;

  v_org_code := replace(trim(p_code), '-', '');

  len := length(v_org_code);
  if len = 9 then
    for i in 1 .. 8 loop
      sigma := sigma + substr(v_org_code, i, 1) * a(i);
    end loop;
    if mod(sigma, 11) = 1 then
      v_result := substr(v_org_code, 1, 8) || 'X';
    else
      v_result := substr(v_org_code, 1, 8) || to_char(11 - mod(sigma, 11));
    end if;
  end if;
  if v_result = v_org_code then
    return '1';
  else
    v_right_code := substr(v_result, 1, 8) || '-' || substr(v_result, 9, 1);
    --dbms_output.put_line('校验位错误,应该是:' || v_right_code);

    return '3';

  end if;
exception
  when others then
    begin

      --dbms_output.put_line('计算时出现异常: ' || sqlerrm);

      return '4';
    end;
end;