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

Responder a