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;