Embora pelo cálculo sejam cpf válidos, tomem cuidado com as combinações
11111111111, 22222222222, ..., 88888888888, 99999999999.
Esses CPF não são aceitos e emitidos pela Receita Federal e vários
deles são cancelados por multiplicidade.
Abaixo função que agrega verificação cnpj / cpf.
Um abraço.
Rudinei Dias
--------------------------------------------------------------------------------------------------------------
-- Function: f_cnpjcpf(integer, character)
-- DROP FUNCTION f_cnpjcpf(integer, character);
CREATE OR REPLACE FUNCTION f_cnpjcpf(integer, character)
RETURNS integer AS
$BODY$
DECLARE
-- Argumentos
-- Tipo de verificacao : 0 (PJ), 1 (PF) e 2 (Livre)
pTipo ALIAS FOR $1;
-- Numero do documento
pNumero ALIAS FOR $2;
-- Variaveis
i INT4; -- Contador
iProd INT4; -- Somatório
iMult INT4; -- Fator
iDigito INT4; -- Digito verificador calculado
sNumero VARCHAR(20); -- numero do docto completo
BEGIN
-- *****************************************************
-- Função: f_cnpjcpf
-- Objetivo:
-- Validar o número do documento especificado
-- (CNPJ ou CPF) ou não (livre)
-- Argumentos:
-- Pessoa [Jurídica(0),Física(1) ou
-- Livre(2)] (integer), Número com dígitos
-- verificadores e sem pontuação (bpchar)
-- Retorno:
-- -1: Tipo de Documento invalido.
-- -2: Caracter inválido no numero do documento.
-- -3: Numero do Documento invalido.
-- 1: OK (smallint)
-- *****************************************************
--
-- verifica Argumentos validos
IF (pTipo < 0) OR (pTipo > 2) THEN
RETURN -1;
END IF;
-- se for Livre, nao eh necessario a verificacao
IF pTipo = 2 THEN
RETURN 1;
END IF;
sNumero := trim(pNumero);
FOR i IN 1..char_length(sNumero) LOOP
IF position(substring(sNumero, i, 1) in '1234567890') = 0 THEN
RETURN -2;
END IF;
END LOOP;
sNumero := '';
-- *****************************************************
-- Verifica a validade do CNPJ
-- *****************************************************
IF (char_length(trim(pNumero)) = 14) AND (pTipo = 0) THEN
-- primeiro digito
sNumero := substring(pNumero from 1 for 12);
iMult := 2;
iProd := 0;
FOR i IN REVERSE 12..1 LOOP
iProd := iProd + to_number(substring(sNumero from i for
1),'9') * iMult;
IF iMult = 9 THEN
iMult := 2;
ELSE
iMult := iMult + 1;
END IF;
END LOOP;
iDigito := 11 - (iProd % 11);
IF iDigito >= 10 THEN
iDigito := 0;
END IF;
sNumero := substring(pNumero from 1 for 12) ||
trim(to_char(iDigito,'9')) || '0';
-- segundo digito
iMult := 2;
iProd := 0;
FOR i IN REVERSE 13..1 LOOP
iProd := iProd + to_number(substring(sNumero from i for
1),'9') * iMult;
IF iMult = 9 THEN
iMult := 2;
ELSE
iMult := iMult + 1;
END IF;
END LOOP;
iDigito := 11 - (iProd % 11);
IF iDigito >= 10 THEN
iDigito := 0;
END IF;
sNumero := substring(sNumero from 1 for 13) || trim(to_char(iDigito,'9'));
END IF;
-- *****************************************************
-- Verifica a validade do CPF
-- *****************************************************
IF (char_length(trim(pNumero)) = 11) AND (pTipo = 1) THEN
-- primeiro digito
iDigito := 0;
iProd := 0;
sNumero := substring(pNumero from 1 for 9);
FOR i IN 1..9 LOOP
iProd := iProd + (to_number(substring(sNumero from i for
1),'9') * (11 - i));
END LOOP;
iDigito := 11 - (iProd % 11);
IF (iDigito) >= 10 THEN
iDigito := 0;
END IF;
sNumero := substring(pNumero from 1 for 9) ||
trim(to_char(iDigito,'9')) || '0';
-- segundo digito
iProd := 0;
FOR i IN 1..10 LOOP
iProd := iProd + (to_number(substring(sNumero from i for
1),'9') * (12 - i));
END LOOP;
iDigito := 11 - (iProd % 11);
IF (iDigito) >= 10 THEN
iDigito := 0;
END IF;
sNumero := substring(sNumero from 1 for 10) || trim(to_char(iDigito,'9'));
END IF;
-- faz a verificacao do digito verificador calculado
IF pNumero = sNumero::bpchar THEN
RETURN 1;
ELSE
RETURN -3;
END IF;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION f_cnpjcpf(integer, character) OWNER TO pgsql;
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral