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é 🙂

 

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *