Oi! Seja bem-vindo!
Hoje vamos validar CPFs e CNPJs no SQL Server. Do cálculo matemático a exemplos de código, te mostrarei na prática como conferir se um documento está correto.
CPF e CNPJ, o que são?
Se você é estrangeiro ou não conhece a fundo, CPF e CNPJ são abreviações para:
== CPF: Cadastro Nacional de Pessoa Física
== CNPJ:Cadastro Nacional de Pessoa Jurídica (empresa)
Atualmente, essas são as formas de identificação principais de uma pessoa (CPF) ou empresa (CNPJ) junto a empresas, bancos e órgãos governamentais.
Dada a importância desses documentos, é importante assegurar que nosso banco de dados não permita a inclusão de números inválidos. Então hoje, vou te mostrar como validar um CPF ou CNPJ no seu SQL Server. Porém, o tutorial vai além: Te mostro como é feito o cálculo, assim se você estiver em outro banco como Oracle, MySQL, Postgree ou outro, você pode implementar a mesma lógica.
Como validar CPFs e CNPJs no SQL Server
Aqui vai o script SQL que utilizei no vídeo:
------------------------------------------------------- -- Como validar CPFs e CNPJs no SQL Server ------------------------------------------------------- use master if db_id('curso') is not null drop database curso go create database curso go use curso go create function valida_cpf_cnpj (@documento varchar(18)) returns bit as begin -- Remove caracteres declare @doc varchar(14) = '' ;with split as ( select 1 as id, substring(@documento, 1, 1) as algarismo union all select id + 1, substring(@documento, id + 1, 1) from split where id < len(@documento) ) select @doc += algarismo from split where algarismo like '[0-9]' -- variáveis declare @doc_len int = len(@doc), @doc_digito1 int = substring(@doc, len(@doc) - 1, 1), @doc_digito2 int = substring(@doc, len(@doc), 1), @loop_digitos_verificadores int = 1, @posicao_proximo_algarismo int, @somatoria_algarismos_x_coeficientes int, @coeficiente_multiplicador int, @algarismo int, @resto_divisao_inteira int, @digito_calculado1 int, @digito_calculado2 int -- loop: executa uma validação para cada um dos digitos (começa em 1 termina em 2) while @loop_digitos_verificadores <= 2 begin select @somatoria_algarismos_x_coeficientes = 0, @coeficiente_multiplicador = 2, @posicao_proximo_algarismo = @doc_len + @loop_digitos_verificadores - 3 -- loop: Uma repetição para cada algarismo da raiz do cnpj ou cpf while @posicao_proximo_algarismo >= 0 begin select @algarismo = substring(@doc, @posicao_proximo_algarismo, 1), @somatoria_algarismos_x_coeficientes += @algarismo * @coeficiente_multiplicador, @coeficiente_multiplicador = @coeficiente_multiplicador + 1, @posicao_proximo_algarismo -= 1 --print '@algarismo: ' + convert(varchar, @algarismo) --print '@coeficiente_multiplicador: ' + convert(varchar, @coeficiente_multiplicador - 1) --print 'produto: ' + convert(varchar, @algarismo * (@coeficiente_multiplicador - 1)) --print '@somatoria_algarismos_x_coeficientes (somatória atual): ' + convert(varchar, @somatoria_algarismos_x_coeficientes) -- Se for um cnpj reinicia a contagem de coeficientes (para cpf continua) if @doc_len > 11 and @coeficiente_multiplicador > 9 set @coeficiente_multiplicador = 2 end --print '@somatoria_algarismos_x_coeficientes (somatória final): ' + convert(varchar, @somatoria_algarismos_x_coeficientes) set @resto_divisao_inteira = 11 - (@somatoria_algarismos_x_coeficientes % 11) --print '@resto_divisao_inteira: ' + convert(varchar, @resto_divisao_inteira) if (@resto_divisao_inteira = 10) set @resto_divisao_inteira = 0 if @loop_digitos_verificadores = 1 set @digito_calculado1 = @resto_divisao_inteira else set @digito_calculado2 = @resto_divisao_inteira set @loop_digitos_verificadores += 1 end return -- select case when @digito_calculado1 = @doc_digito1 and @digito_calculado2 = @doc_digito2 then 1 else 0 end end /* -- Teste: Matriz de cálculo: declare @doc varchar(14) = 12345678000195 ;with a as ( select -- validação primeiro dígito id = 1, posicao_d1 = len(@doc) - 2, coeficiente_d1 = 2, elemento_d1 = substring(@doc, len(@doc) - 2, 1), produto_d1 = substring(@doc, len(@doc) - 2, 1) * 2, -- validação segundo dígito posicao_d2 = len(@doc) - 1, coeficiente_d2 = 2, elemento_d2 = substring(@doc, len(@doc) - 1, 1), produto_d2 = substring(@doc, len(@doc) - 1, 1) * 2 union all select -- digito 1 id + 1, posicao_d1 - 1, case when coeficiente_d1 > 8 and len(@doc) = 14 then 2 else coeficiente_d1 + 1 end, substring(@doc, posicao_d1 - 1, 1), substring(@doc, posicao_d1 - 1, 1) * case when coeficiente_d1 > 8 and len(@doc) = 14 then 2 else coeficiente_d1 + 1 end, -- digito 2 posicao_d2 - 1, case when coeficiente_d2 > 8 and len(@doc) = 14 then 2 else coeficiente_d2 + 1 end, substring(@doc, posicao_d2 - 1, 1), substring(@doc, posicao_d2 - 1, 1) * case when coeficiente_d2 > 8 and len(@doc) = 14 then 2 else coeficiente_d2 + 1 end from a where posicao_d2 - 1 > 0) select * from a from ( select sum(produto_d1) produto_d1, sum(produto_d2) produto_d2 from a) somatoria -- Exemplos válidos select dbo.valida_cpf_cnpj ('12345678000195') select dbo.valida_cpf_cnpj ('12345678909') select dbo.valida_cpf_cnpj ('12.345.678/0001-95') select dbo.valida_cpf_cnpj ('123.456.789-09') -- Exemplos inválidos select dbo.valida_cpf_cnpj ('12345678910') select dbo.valida_cpf_cnpj ('12.345.678/0001-90') */
CONCLUSÃO
Admito que falar de cálculo, ou fazer cálculos as vezes é meio chato… 🙂 Mas como você viu não é nada complicado. Principalmente, a função que valida o CPF ou CNPJ já está na mão, prontinha para uso.
Sei o quanto é importante criar mecanismos de proteção para um banco de dados, disso eu sou fã… então montei esse artigo pensando em te inspirar um pouco a proteger seu banco também. Acredite: Tem horas que esse tipo de coisa salva a nossa pele… hohohohoho!
Abraço do seu amigo Josué 🙂