Stored Procedure para a validação de CNPJ SQL Firebird
Fala galera de Delphi, tudo beleza?
Continuando com o parênteses de SQL para quem trabalha com Firebird, vamos a mais
uma dica interessante.
Diversas vezes precisei validar CNPJs de base de dados, mas sempre precisando fazer a validação
via aplicação, o que acabava aumentando o tempo necessário do trabalho além de não poder
resolver tudo via banco de dados.
Pesquisei e felizmente encontrei uma alternativa para fazer a validação diretamente
via SQL. A solução foi criar uma Stored Procedure que é a responsável pela validação!
Esta versão já está validada para Firebird 3.0 é não faz uso de UDFs!
Vamos ao código!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
| SET TERM ^ ;
CREATE OR ALTER PROCEDURE UTIL_IS_VALID_CNPJ (
CNPJ VARCHAR(30))
RETURNS (
VALIDO SMALLINT)
AS
DECLARE variable TMP_CNPJ VARCHAR(30);
DECLARE variable I INTEGER;
DECLARE variable L INTEGER;
DECLARE variable T INTEGER;
BEGIN
-- código da comunidade show delphi, adaptado por Giovani Da Cruz
CNPJ = TRIM(:CNPJ);
/* DIGITOS IDENTICOS */
IF (
(CHARACTER_LENGTH(CNPJ) <> 14) OR
(CNPJ = '00000000000000') OR (CNPJ = '11111111111111') OR
(CNPJ = '22222222222222') OR (CNPJ = '33333333333333') OR (CNPJ = '44444444444444')OR
(CNPJ = '55555555555555') OR (CNPJ = '66666666666666') OR (CNPJ = '77777777777777')OR
(CNPJ = '88888888888888') OR (CNPJ = '99999999999999')
) THEN
BEGIN
VALIDO = 0;
SUSPEND;
Exit;
END
I = 1;
TMP_CNPJ = '';
while (I <= CHAR_LENGTH(CNPJ)) do
BEGIN
IF (SUBSTRING(CNPJ FROM I FOR 1) BETWEEN '0' AND '9') THEN
TMP_CNPJ = TMP_CNPJ || SUBSTRING(CNPJ FROM I FOR 1);
I = I + 1;
END
IF (CHAR_LENGTH(TMP_CNPJ) <> 14) THEN
BEGIN
VALIDO = 0;
suspend;
exit;
END
L = 0;
while (L < 2) do
BEGIN
I = 1;
T = 0;
while (I < 13 + L) do
BEGIN
T = T + (MOD(20 - I + L, 8) + 2) * CAST(SUBSTRING(TMP_CNPJ FROM I FOR 1) AS INTEGER);
I = I + 1;
END
T = MOD(T, 11);
IF (T < 2) THEN
BEGIN
T = 0;
END
ELSE
BEGIN
T = 11 - T;
END
IF (T <> CAST(SUBSTRING(TMP_CNPJ FROM 13 + L FOR 1) AS INTEGER)) THEN
BEGIN
VALIDO = 0;
suspend;
exit;
END
L = L + 1;
END
VALIDO = 1;
suspend;
END
^
SET TERM ; ^ |
SET TERM ^ ;
CREATE OR ALTER procedure UTIL_IS_VALID_CNPJ (
CNPJ varchar(30))
returns (
VALIDO smallint)
as
declare variable TMP_CNPJ varchar(30);
declare variable I integer;
declare variable L integer;
declare variable T integer;
begin
-- código da comunidade show delphi, adaptado por Giovani Da Cruz
CNPJ = trim(:CNPJ);
/* DIGITOS IDENTICOS */
IF (
(character_length(CNPJ) <> 14) or
(CNPJ = '00000000000000') OR (CNPJ = '11111111111111') OR
(CNPJ = '22222222222222') OR (CNPJ = '33333333333333') OR (CNPJ = '44444444444444')OR
(CNPJ = '55555555555555') OR (CNPJ = '66666666666666') OR (CNPJ = '77777777777777')OR
(CNPJ = '88888888888888') or (CNPJ = '99999999999999')
) THEN
BEGIN
VALIDO = 0;
SUSPEND;
Exit;
END
I = 1;
TMP_CNPJ = '';
while (I <= char_length(CNPJ)) do
begin
if (substring(CNPJ from I for 1) between '0' and '9') then
TMP_CNPJ = TMP_CNPJ || substring(CNPJ from I for 1);
I = I + 1;
end
if (char_length(TMP_CNPJ) <> 14) then
begin
VALIDO = 0;
suspend;
exit;
end
L = 0;
while (L < 2) do
begin
I = 1;
T = 0;
while (I < 13 + L) do
begin
T = T + (mod(20 - I + L, 8) + 2) * cast(substring(TMP_CNPJ from I for 1) as integer);
I = I + 1;
end
T = mod(T, 11);
if (T < 2) then
begin
T = 0;
end
else
begin
T = 11 - T;
end
if (T <> cast(substring(TMP_CNPJ from 13 + L for 1) as integer)) then
begin
VALIDO = 0;
suspend;
exit;
end
L = L + 1;
end
VALIDO = 1;
suspend;
end
^
SET TERM ; ^
A stored procedure foi montada com base no seguinte post: https://www.firebase.com.br/artigo.php?id=3061
(FireBase – mais só acessível para usuários logados).
Maravilha, vamos ao exemplo de uso!
1
2
3
4
5
6
7
8
9
10
11
12
| SELECT
-- válido gerado pelo gerador de cnpj do show delphi
(SELECT y.valido FROM util_is_valid_cnpj('78651494000161') y),
-- inválido
(SELECT y.valido FROM util_is_valid_cnpj('00000000000000') y),
-- inválido
(SELECT y.valido FROM util_is_valid_cnpj('01294580043417') y)
FROM rdb$database |
select
-- válido gerado pelo gerador de cnpj do show delphi
(select y.valido from util_is_valid_cnpj('78651494000161') y),
-- inválido
(select y.valido from util_is_valid_cnpj('00000000000000') y),
-- inválido
(select y.valido from util_is_valid_cnpj('01294580043417') y)
from rdb$database
Assim você pode facilitar as suas validação diretamente via SQL.
Aproveite e conheça o gerador de CNPJ e CPF do Show Delphi para aprimorar
seus testes. Visite: https://showdelphi.com.br/gerador-de-cpf-e-cnpj/
Espero que seja útil a todos!
Dúvidas ou sugestões? Deixe o seu comentário!
-
Giovani Da Cruz
-
3.316 views
- 2 comentários
- 29 de agosto de 2019
Está gostando do conteúdo? Considere pagar um cafezinho para nossa equipe!
Posts Relacionados - Continue Aprendendo
Também tive esse problema na criação da procedure, mas foi só tirar as linhas
— código da comunidade show delphi, adaptado por Giovani Da Cruz e
/* DIGITOS IDENTICOS */
não sei por que mas pude criar e testar.
Funciona bem, é diferente do método que uso mas é boa, parabéns e obrigado
Oliveira Dos Santos, provavelmente o erro “Malformed string.” ocorre por causa dos acentos nos comentários.
Se remove-los, provavelmente funcionará.
Isso pode ocorrer em alguns casos dependebdo do charset ou colatte escolhidos.