Skip to content

Commit ed9bf1e

Browse files
committed
Add validacao de CNPJ alfanumerico
1 parent 43c30ea commit ed9bf1e

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed

Misc/fn.ValidarCNPJ-Alfa.sql

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/*#info
2+
3+
# Autor
4+
Rodrigo Ribeiro Gomes
5+
(adaptado de Fausto F. Branco em http://dba-sqlserver.blogspot.com.br/2009/11/gerar-cpf-valido.htm
6+
7+
# Descricao
8+
Função para validar se o CNPJ (incluindo alfanumérico) é válido ou não.
9+
Criado como uma inline table-valued function para performance, quando usado com muitas linhas.
10+
Se valido, a coluna valido será 1, caso contrario nao é valido.
11+
Segue as regras descrita em: https://www.gov.br/receitafederal/pt-br/centrais-de-conteudo/publicacoes/documentos-tecnicos/cnpj
12+
13+
Exemplo de uso:
14+
select * from dbo.ValidarCnpj('VCVHEYUW000118')
15+
16+
17+
Validando vários cnpjs de uma vez:
18+
19+
Suponha que você tenha os cnpjs na tabela empresas, coluna cnpj.
20+
Para validar:
21+
22+
select
23+
e.cnpj
24+
,v.valido
25+
from
26+
empresas e
27+
cross apply
28+
dbo.ValidarCnpj(e.cnpj) v
29+
30+
No final o scripts deixei alguns comparativos de performance em algumas maquinas que exeucutei.
31+
Se você mais testes, pode atualizar o script (mesmo padrão), que eu aprovo o commit.
32+
33+
*/
34+
35+
USE master
36+
GO
37+
38+
IF OBJECT_ID('dbo.ValidarCnpj','IF') IS NULL
39+
EXEC('CREATE FUNCTION dbo.ValidarCnpj() RETURNS TABLE AS RETURN (SELECT 1 as StubVersion)')
40+
GO
41+
42+
ALTER FUNCTION dbo.ValidarCnpj(@cnpj varchar(14))
43+
RETURNS TABLE
44+
AS RETURN (
45+
46+
SELECT
47+
valido = convert(bit,case
48+
when nd1 = d1 AND nd2 = d2 THEN 1
49+
else 0
50+
end)
51+
,*
52+
53+
FROM
54+
(
55+
SELECT
56+
C2BASE.*
57+
,d2 = CASE
58+
WHEN d2calc%11 < 2 THEN 0
59+
ELSE 11-d2calc%11
60+
END
61+
62+
FROM (
63+
SELECT
64+
C1.*
65+
,d2calc = n1*6 + n2*5 + n3*4 + n4*3 + n5*2 + n6*9 + n7*8 + n8*7 + n9*6 + n10*5 + n11*4 + + n12*3 + d1*2
66+
FROM
67+
(
68+
69+
SELECT
70+
CASE
71+
WHEN d1calc%11 < 2 THEN 0
72+
ELSE 11-d1calc%11
73+
END as d1
74+
,C1BASE.*
75+
FROM
76+
(
77+
SELECT
78+
*
79+
,d1calc = n1*5 + n2*4 + n3*3 + n4*2 + n5*9 + n6*8 + n7*7 + n8*6 + n9*5 + n10*4 + n11*3 + + n12*2
80+
FROM
81+
(
82+
SELECT
83+
ascii(substring(@cnpj,1,1))-48 as n1
84+
,ascii(substring(@cnpj,2,1))-48 as n2
85+
,ascii(substring(@cnpj,3,1))-48 as n3
86+
,ascii(substring(@cnpj,4,1))-48 as n4
87+
,ascii(substring(@cnpj,5,1))-48 as n5
88+
,ascii(substring(@cnpj,6,1))-48 as n6
89+
,ascii(substring(@cnpj,7,1))-48 as n7
90+
,ascii(substring(@cnpj,8,1))-48 as n8
91+
,ascii(substring(@cnpj,9,1))-48 as n9
92+
,ascii(substring(@cnpj,10,1))-48 as n10
93+
,ascii(substring(@cnpj,11,1))-48 as n11
94+
,ascii(substring(@cnpj,12,1))-48 as n12
95+
,substring(@cnpj,13,1) as nd1
96+
,substring(@cnpj,14,1) as nd2
97+
) R
98+
) C1BASE
99+
) C1
100+
) C2BASE
101+
) C2
102+
103+
)
104+
GO
105+
106+
107+
108+
109+
110+
/*
111+
Teste de performance (usando a view do script vw.GerarCNPJ-alfa), 100 mil cnpjs, ~10% invalido:
112+
113+
Resultados:
114+
sql 2025 ctp 2.0 17.0.700.9, Intel Core i7-10750h, cpu @2.69Ghz (clock real > 4Ghz), Memoria 2667Mhz
115+
SQL Server Execution Times:
116+
CPU time = 1094 ms, elapsed time = 1274 ms.
117+
118+
119+
sql 2019 cu16 15.0.4223.1, VM Azure Standard_E4as_v4, AMD EPYC 7452-32 Core Processor (vm com 4 cores), base speed 2.35
120+
SQL Server Execution Times:
121+
CPU time = 2203 ms, elapsed time = 3283 ms.
122+
123+
Script de teste:
124+
set statistics time,io on;
125+
126+
drop table if exists #cnpjs ;
127+
128+
select top 100000
129+
case
130+
when p <= 10 then stuff(cnpj,1,1,'A')
131+
else cnpj
132+
end as cnpj
133+
,p
134+
into
135+
#cnpjs
136+
from
137+
sys.all_columns a1,sys.all_columns a2
138+
cross apply
139+
dbo.vwGeraCNPJAlfa cnpj
140+
CROSS APPLY (
141+
SELECT p = abs(checksum(newid()))%100
142+
) R
143+
144+
145+
select
146+
*
147+
from
148+
#cnpjs c
149+
cross apply
150+
dbo.ValidarCnpj(c.cnpj) v
151+
152+
153+
sobre os testes:
154+
As informações são apenas da última query (o select na tab temporaira + funcao).
155+
Em teoria, essa é uma query que vai moer CPU e memória, I/O deve ser irrevalante aqui, mas se você testar em um ambiente cmo alta atividade, pode ser que seja afetado pelo I/O, devido apressão na memória.
156+
No gera, não vejo impacto sinificativo.
157+
158+
CPU vai gastar, obviamente, devido ser uma fução que basicamente faz algumas operações simples.
159+
E memória, devido a necessidae de ler da tabela com vários dados (o que pode não caber no cache da cpu, e provavelmente vai demanda ralgumas leituras, por isso, coloquei as infos de memória, pois isso é um variável que impacta no tempo)
160+
161+
162+
163+
164+
*/

0 commit comments

Comments
 (0)