Pular para o conteúdo
ValidadorCNPJ Gerar CNPJ

SQL · código pronto

Validar CNPJ alfanumérico em SQL

Função de validação de CNPJ alfanumérico em SQL para PostgreSQL, SQL Server, MySQL e Oracle.

Testar um CNPJ agora Gerar massa de teste

Validar no banco é útil como última linha de defesa (constraint) e para auditar bases legadas. Abaixo, a versão PostgreSQL completa e o equivalente em SQL Server.

O algoritmo é sempre o mesmo: cada caractere vale o seu código ASCII menos 48 (0=0 … 9=9, A=17 … Z=42), os pesos vão de 2 a 9 da direita para a esquerda, soma-se tudo, divide-se por 11 e o dígito é 0 quando o resto é menor que 2, ou 11 menos o resto. Ver a conta detalhada.

Código completo

validação de CNPJ alfanumérico em SQL
-- PostgreSQL
CREATE OR REPLACE FUNCTION cnpj_limpar(valor text)
RETURNS text
LANGUAGE sql IMMUTABLE STRICT AS $$
  SELECT regexp_replace(upper(valor), '[^0-9A-Z]', '', 'g');
$$;

CREATE OR REPLACE FUNCTION cnpj_digito(sequencia text)
RETURNS int
LANGUAGE plpgsql IMMUTABLE STRICT AS $$
DECLARE
  tamanho int := length(sequencia);
  soma    int := 0;
  i       int;
  peso    int;
  resto   int;
BEGIN
  FOR i IN 1..tamanho LOOP
    peso := ((tamanho - i) % 8) + 2;
    soma := soma + (ascii(substr(sequencia, i, 1)) - 48) * peso;
  END LOOP;

  resto := soma % 11;

  IF resto < 2 THEN
    RETURN 0;
  END IF;

  RETURN 11 - resto;
END;
$$;

CREATE OR REPLACE FUNCTION cnpj_valido(valor text)
RETURNS boolean
LANGUAGE plpgsql IMMUTABLE AS $$
DECLARE
  cnpj  text;
  base  text;
  d1    int;
  d2    int;
BEGIN
  IF valor IS NULL THEN
    RETURN false;
  END IF;

  cnpj := cnpj_limpar(valor);

  IF cnpj !~ '^[0-9A-Z]{12}[0-9]{2}$' THEN
    RETURN false;
  END IF;

  base := substr(cnpj, 1, 12);
  d1 := cnpj_digito(base);
  d2 := cnpj_digito(base || d1::text);

  RETURN substr(cnpj, 13, 2) = d1::text || d2::text;
END;
$$;

-- Constraint na tabela
ALTER TABLE empresa
  ALTER COLUMN cnpj TYPE varchar(14),
  ADD CONSTRAINT empresa_cnpj_valido CHECK (cnpj_valido(cnpj));

-- Auditoria: quais registros da base atual reprovariam?
SELECT id, cnpj FROM empresa WHERE NOT cnpj_valido(cnpj);

Testes e integração com o framework

sql server (T-SQL)
-- SQL Server
CREATE OR ALTER FUNCTION dbo.CnpjDigito (@Sequencia varchar(13))
RETURNS int
AS
BEGIN
    DECLARE @Tamanho int = LEN(@Sequencia);
    DECLARE @Soma int = 0, @i int = 1, @Peso int, @Resto int;

    WHILE @i <= @Tamanho
    BEGIN
        SET @Peso = ((@Tamanho - @i) % 8) + 2;
        SET @Soma = @Soma + (ASCII(SUBSTRING(@Sequencia, @i, 1)) - 48) * @Peso;
        SET @i = @i + 1;
    END

    SET @Resto = @Soma % 11;

    RETURN CASE WHEN @Resto < 2 THEN 0 ELSE 11 - @Resto END;
END;
GO

CREATE OR ALTER FUNCTION dbo.CnpjValido (@Valor varchar(30))
RETURNS bit
AS
BEGIN
    DECLARE @Cnpj varchar(30) = UPPER(REPLACE(REPLACE(REPLACE(REPLACE(
        ISNULL(@Valor, ''), '.', ''), '-', ''), '/', ''), ' ', ''));

    IF LEN(@Cnpj) <> 14 RETURN 0;
    IF @Cnpj LIKE '%[^0-9A-Z]%' RETURN 0;
    IF SUBSTRING(@Cnpj, 13, 2) LIKE '%[^0-9]%' RETURN 0;

    DECLARE @Base varchar(12) = LEFT(@Cnpj, 12);
    DECLARE @D1 int = dbo.CnpjDigito(@Base);
    DECLARE @D2 int = dbo.CnpjDigito(@Base + CAST(@D1 AS varchar(1)));

    RETURN CASE
        WHEN SUBSTRING(@Cnpj, 13, 2) = CAST(@D1 AS varchar(1)) + CAST(@D2 AS varchar(1))
        THEN 1 ELSE 0
    END;
END;
GO

Detalhes que costumam quebrar em SQL

Casos de teste recomendados

Cubra pelo menos estes cenários — eles pegam praticamente todos os erros de implementação:

EntradaEsperadoO que testa
12.ABC.345/01DE-35válidoexemplo oficial, com máscara
12abc34501de35válidonormalização para maiúsculas
11.222.333/0001-81válidocompatibilidade com o formato numérico
11.222.333/0001-82inválidodígito verificador errado
12ABC34501DEABinválidoletra no dígito verificador
12ABC34501DE3inválidotamanho incorreto
00.000.000/0000-00inválidosequência repetida
"" / nullinválidoentrada vazia sem exceção

Precisa de mais massa de teste? O gerador produz até 500 CNPJs alfanuméricos válidos de uma vez, com opção de baixar em .txt.

O mesmo algoritmo em outras linguagens

Dúvidas sobre CNPJ alfanumérico em SQL

Preciso de alguma biblioteca para validar CNPJ alfanumérico em SQL?

Não. O código desta página usa apenas a biblioteca padrão de SQL — são cerca de 30 linhas. Bibliotecas de terceiros só valem a pena se você também precisa de formatação, geração e validação de outros documentos; e, nesse caso, confira se a versão instalada já suporta o formato alfanumérico.

A mesma função valida CNPJ numérico e alfanumérico em SQL?

Sim. Como o valor de cada dígito é o próprio dígito (código ASCII menos 48), o algoritmo alfanumérico produz o mesmo resultado do antigo para números. Você não precisa manter duas funções nem ramificar por formato.

Como testar se a implementação está certa?

Use o exemplo oficial da Receita Federal: a base 12ABC34501DE tem dígitos verificadores 35, formando 12.ABC.345/01DE-35. Confira também um CNPJ numérico conhecido, como 11.222.333/0001-81, e um inválido, como 11.222.333/0001-82.

O que mais precisa mudar além da função de validação?

O tipo da coluna no banco (de numérico para VARCHAR(14)), qualquer conversão para inteiro no caminho do dado, as máscaras de entrada e as regex espalhadas por validações e relatórios. A função de validação costuma ser a parte mais fácil da migração.