[firebase-br] Uma contribuição para os colegas: uma nova versão de rotina de validação de CPF e CNPJ
Francisco Carlos da Rocha Gomes
fcarlos em cpafac.embrapa.br
Seg Fev 8 13:04:45 -03 2010
Colegas,
A lista de Firebird tem me ajudado tanto e acho que é importante eu
contribuir também com os colegas.
Eu estava procurando uma boa rotina de validação de CPF e CNPJ e
encontrei apenas a dica no site do Firebase que me serviu de base para
fazer uma rotina mais simples e "robusta" (que aceita qualquer coisa na
entrada), que encaminho abaixo para os colegas.
Cordial abraço,
Francisco Carlos
Embrapa Acre
-------------------------------------------------------
DECLARE EXTERNAL FUNCTION RTRIM
CSTRING(80)
RETURNS CSTRING(80) FREE_IT
ENTRY_POINT 'IB_UDF_rtrim' MODULE_NAME 'ib_udf';
-------------------------------------------------------
DECLARE EXTERNAL FUNCTION STRLEN
CSTRING(32767)
RETURNS INTEGER BY VALUE
ENTRY_POINT 'IB_UDF_strlen' MODULE_NAME 'ib_udf';
-------------------------------------------------------
DECLARE EXTERNAL FUNCTION SUBSTRLEN
CSTRING(255), SMALLINT, SMALLINT
RETURNS CSTRING(255) FREE_IT
ENTRY_POINT 'IB_UDF_substrlen' MODULE_NAME 'ib_udf';
-------------------------------------------------------
DECLARE EXTERNAL FUNCTION MOD
INTEGER, INTEGER
RETURNS DOUBLE PRECISION BY VALUE
ENTRY_POINT 'IB_UDF_mod' MODULE_NAME 'ib_udf';
-------------------------------------------------------
SET TERM ^ ;
CREATE PROCEDURE PEGANUMSTR (
str varchar(20))
returns (
numstr varchar(20),
tamstr_completo integer,
tamstr_num integer)
as
declare variable j integer;
declare variable c char(1);
begin
tamstr_completo = strlen(str);
if ((str is null) or (str = '') or (tamstr_completo = 0)) then
begin
numstr = null;
end
else
begin
numstr = '';
tamstr_num = 0;
j = 1;
while (J <= tamstr_completo)do
begin
c = substrlen(str, j, 1);
if ((c = '0') or (c = '1') or (c = '2') or (c = '3') or (c = '4')
or (c = '5') or (c = '6') or (c = '7') or (c = '8') or (c =
'9')) then
begin
numstr = numstr || c;
tamstr_num = tamstr_num + 1;
end
j = j + 1;
end
if (numstr = '') then
numstr = null;
suspend;
end
end ^
SET TERM ; ^
-------------------------------------------------------
SET TERM ^ ;
CREATE PROCEDURE CPFCNPJ_OK (
pcpfcnpj varchar(20))
returns (
cpfcnpj_ok char(1),
cpfcnpj_info varchar(20),
cpfcnpj_calc varchar(20))
as
declare variable i integer;
declare variable posic integer;
declare variable peso integer;
declare variable soma integer;
declare variable digver integer;
declare variable limite integer;
declare variable ehcpf char(1);
begin
cpfcnpj_ok = null;
if (pcpfcnpj is not null) then
begin
ehcpf = null;
select numstr, tamstr_num
from peganumstr(:pcpfcnpj)
into :cpfcnpj_info, :i;
if (i = 11) then
begin
ehcpf = 's';
limite = 10;
end
else
if (i = 14) then
begin
ehcpf = 'n';
limite = 9;
end
if (ehcpf is not null) then
begin
cpfcnpj_calc = substrlen(cpfcnpj_info, 1, i-2);
i = 0;
while (i <= 1) do
begin
i = i + 1;
soma = 0;
peso = 1;
posic = strlen(cpfcnpj_calc);
while (posic >= 1) do
begin
peso = peso + 1;
if (peso > limite) then
peso = 2;
soma = soma + cast(substrlen(cpfcnpj_calc, posic, 1) as
integer) * peso;
posic = posic - 1;
end
digver = mod(soma, 11);
if ((digver <> 0) and (digver <> 1)) then
digver = 11 - digver;
else
digver = 0;
cpfcnpj_calc = cpfcnpj_calc || digver;
if (ehcpf = 's') then
limite = limite + 1;
end
end
end
if (cpfcnpj_calc = cpfcnpj_info) then
cpfcnpj_ok = 's';
else
cpfcnpj_ok = 'n';
suspend;
end ^
SET TERM ; ^
Mais detalhes sobre a lista de discussão lista