Validação de CPF e CNPJ
A validação de campos como CPF e CNPJ pelo banco é considerado uma boa politica de segurança ou depende?
Em que situações deve ser feito tanto na aplicação como no banco?
Em que situações deve ser feito tanto na aplicação como no banco?
Mariana Carvalho
Curtidas 0
Melhor post
Jothaz
16/03/2015
Certamente na aplicação.
Ao encapsular regras de negócio no banco de dados você dificulta a migração para outros bancos de dados.
Quando todas a regras de negócio ficam na aplicação você dá atomicidade a mesma o que a torna mais legível e de fácil manutenção.
Agora só com informação segue scripts sql para executar a validação.
CPF:
CNPJ:
Ao encapsular regras de negócio no banco de dados você dificulta a migração para outros bancos de dados.
Quando todas a regras de negócio ficam na aplicação você dá atomicidade a mesma o que a torna mais legível e de fácil manutenção.
Agora só com informação segue scripts sql para executar a validação.
CPF:
/* Calculo do Digito Verificador para CPF por: Antonio Rodrigues dos Santos Filho - antonio@aikon.com.br Instruções 1- O CPF deve ser passado contendo apenas os numero. Não coloque os '.' e '/' 2- O resultado da função será o Digito Verificador em char(2) Exemplo: declare @dv as char(2) set @dv = dbo.CalculaCPF ('123456789') print @dv obs: Neste caso o DV = 09 qualquer erro, o resultado do DV será -- */ create function dbo.CalculaCPF (@cpf as varchar(10)) returns char(2) as Begin declare @soma as int, @dv as char(2), @dv1 as int, @dv2 as int, @i as int, @somando as int set @cpf = substring(@cpf, 1, 9) set @dv = '--' -- Teste 1. O cpf nao pode ser tudo 1 ou 2 e etc if not (@cpf = '111111111' or @cpf = '222222222' or @cpf = '333333333' or @cpf = '444444444' or @cpf = '555555555' or @cpf = '666666666' or @cpf = '777777777' or @cpf = '888888888' or @cpf = '999999999' or @cpf = '000000000') begin -- Teste 2. Verifica se o cpf tem os 9 digitos preenchidos If rtrim(Len(@cpf)) = 9 begin --Calcula DV1 (1o Digito Verificador) set @soma = 0 set @somando = 10 set @i = 1 while @i < 10 begin set @soma = @soma + Substring(@cpf, @i, 1) * @somando set @somando = @somando - 1 set @i = @i +1 end set @dv1 = 11 - (@soma - (@soma/11) * 11) If @dv1 > 9 set @dv1 = 0 -- Calcula DV2 (2o Digito Verificador) set @cpf = @cpf + ltrim(str(@dv1)) set @soma = 0 set @somando = 11 set @i = 1 while @i < 11 begin set @soma = @soma + Substring(@cpf, @i, 1) * @somando set @somando = @somando - 1 set @i = @i +1 end set @dv2 = 11 - (@soma - (@soma/11) * 11) If @dv2 > 9 set @dv2= 0 if @dv1 <> 0 begin set @dv = ltrim(str(@dv1 * 10 + @dv2)) end else begin set @dv = '0' + ltrim(str(@dv2)) end End End Return (@dv) End
CNPJ:
/* Calculo do Digito Verificador para CNPJ por: Antonio Rodrigues dos Santos Filho - antonio@aikon.com.br Instruções 1- O CPF deve ser passado contendo apenas os numero. Não coloque os '.' e '/' 2- O resultado da função será o Digito Verificador em char(2) Exemplo: declare @dv as char(2) set @dv = dbo.CalculaCNPJ ('123456780001') print @dv obs: Neste caso o DV = 95 qualquer erro, o resultado do DV será -- */ alter function dbo.CalculaCNPJ (@cnpj as varchar(13)) returns char(2) as Begin declare @soma as int, @dv as char(2), @dv1 as int, @dv2 as int, @i as int, @somando as int, @cnpj1 as char(8) set @cnpj1 = substring(@cnpj, 1, 8) set @dv = '--' -- Teste 1. O cpf nao pode ser tudo 1 ou 2 e etc if not (@cnpj1 = '11111111' or @cnpj1 = '22222222' or @cnpj1 = '33333333' or @cnpj1 = '44444444' or @cnpj1 = '55555555' or @cnpj1 = '66666666' or @cnpj1 = '77777777' or @cnpj1 = '88888888' or @cnpj1 = '99999999' or @cnpj1 = '00000000') begin -- Teste 2. Verifica se o cpf tem os 9 digitos preenchidos If rtrim(Len(@cnpj)) = 12 begin --Calcula DV1 (1o Digito Verificador) set @soma = 0 set @somando = 5 set @i = 1 while @i < 5 begin set @soma = @soma + Substring(@cnpj, @i, 1) * @somando set @somando = @somando - 1 set @i = @i +1 end set @somando = 9 set @i = 5 while @i < 13 begin set @soma = @soma + Substring(@cnpj, @i, 1) * @somando set @somando = @somando - 1 set @i = @i +1 end set @dv1 = 11 - (@soma - (@soma/11) * 11) If @dv1 > 9 set @dv1 = 0 -- Calcula DV2 (2o Digito Verificador) set @cnpj = @cnpj + ltrim(str(@dv1)) set @soma = 0 set @somando = 6 set @i = 1 while @i < 6 begin set @soma = @soma + Substring(@cnpj, @i, 1) * @somando set @somando = @somando - 1 set @i = @i +1 end set @somando = 9 set @i = 6 while @i < 14 begin set @soma = @soma + Substring(@cnpj, @i, 1) * @somando set @somando = @somando - 1 set @i = @i +1 end set @dv2 = 11 - (@soma - (@soma/11) * 11) If @dv2 > 9 set @dv2= 0 if @dv1 <> 0 begin set @dv = ltrim(str(@dv1 * 10 + @dv2)) end else begin set @dv = '0' + ltrim(str(@dv2)) end end end return (@dv) end
GOSTEI 1
Mais Respostas
Mariana Carvalho
10/03/2015
???????????????
GOSTEI 0
Thiago Santana
10/03/2015
No meu ponto de vista, formatações e validações de campos devem ser feitas por parte da aplicação, porém o banco não poderá aceitar valores "inválidos"
GOSTEI 0
Mariana Carvalho
10/03/2015
É parecido com o que vi em outras linguagens, nas minhas pesquisas, bem parecido mesmo. Então em nenhum momento faz-se pelo banco de dados pelo motivo que descreveu.
GOSTEI 0
Jothaz
10/03/2015
É parecido com o que vi em outras linguagens, nas minhas pesquisas, bem parecido mesmo. Então em nenhum momento faz-se pelo banco de dados pelo motivo que descreveu.
Em TI não existe esta abordagem de 8 ou 80, tudo depende do cenário e principalmente de como o analista/projetista entende que é o mais indicado a fazer. Desde que seja embasado em argumentos técnicos viáveis.
Seguindo as melhores práticas a ideia hoje em dia é colocar toda a regra de negócio dentro da aplicação e eis alguns motivos:
Apesar de atualmente todos os bancos de dados seguirem uma especificação padrão (se não me engando SQL-92) cada banco possui suas peculiaridade e especificidades com relação a funções interna o que torna impossível porta um código de um banco para outro sem alterações. Por exemplo a função CAST pode variar assim:
---Oracle - CAST -> ( [ Expression | NULL | ? ] AS Datatype)
---MS SQL Server -> CAST ( expression AS data_type [ ( length ) ] ) ou CONVERT ( data_type [ ( length ) ] , expression [ , style ] )
---PostgreSQL -> CAST ( expressão AS tipo ) AS apelido
---MySQL -> CONVERT(expr USING transcoding_name) ou CAST(character_string AS character_data_type CHARACTER SET charset_name)
Então apesar da DML (Data Manipulation Language - Linguagem de manipulação de dados) ser padrão existem várias diferenças em algumas funções. O que torna a mudança de banco de dados trabalhosa.
Ao deixar as regras de negócio e manipulação dos dados na aplicação fica mais simples desenvolver uma aplicação independente do banco de dados, desde que projetada para isto.
Se a aplicação usar padrões de projeto as regras de negócio ficam separadas facilitando a leitura e a manutenção.
No caso do exemplo acima, se for efetuada qualquer alteração na função você deve alterar o banco de dados e a aplicação e atualizar. E se você tem vários clientes pode ser trabalhoso. Se a regra estiver na aplicação, basta alterar e ficaria mais simples replicar para os clientes.
Quando você usa o tratamento dos dados no banco de dados a lógica fica encapsulada e o desenvolvedor tem de abrir o banco de dados e procurar onde este sendo feito o tratamento, se fica na aplicação é só ir na onde estão as regras de negócio o que facilita.
Agora se você enquanto analista responsável achar que a melhor solução e fazer tudo no banco de dados então faça, basta justificar tecnicamente com equipe do projeto. Afinal ninguém conhece mais do seu sistema/projeto do que quem esta projetando/desenvolvendo.
GOSTEI 0
Mariana Carvalho
10/03/2015
Devemos nos ater ao que convém ao projeto, isso deve ser visto por todos os envolvidos, entendi perfeitamente Jothaz, é uma decisão que deve ser avaliada.
Obrigada.
Obrigada.
GOSTEI 0
Gabriel Queiroz
10/03/2015
Acho que voce precisa usar data annotation
GOSTEI 0
Gabriel Queiroz
10/03/2015
Mas no caso eu estou desenvolvendo com code first então trato disto dentro da aplicação mesmo
GOSTEI 0
Thiago Santana
10/03/2015
Acho que esse tipo de validação deve ser feita do lado do cliente, pois não seria necessário ir até a camada de dados para efetuar uma validação desse nível.
GOSTEI 0
Mariana Carvalho
10/03/2015
Acho que voce precisa usar data annotation
Me explique o é o data annotation, por favor.
GOSTEI 0
Mariana Carvalho
10/03/2015
Acho que esse tipo de validação deve ser feita do lado do cliente, pois não seria necessário ir até a camada de dados para efetuar uma validação desse nível.
A linguagem responsavel? Esse processo no banco o tornaria mais lento não é, um trabalho extra para ele.
GOSTEI 0
Jothaz
10/03/2015
Acho que esse tipo de validação deve ser feita do lado do cliente, pois não seria necessário ir até a camada de dados para efetuar uma validação desse nível.
A linguagem responsavel? Esse processo no banco o tornaria mais lento não é, um trabalho extra para ele.
A questão não trabalho, pois o este esforço para o BD é minimo.
Seria questão de melhores práticas.
Ao colocar este tipo de operação no código você ganha em:
1-Legibilidade - fica mais fácil e simples acessar o conteúdo do método usado para consistir, não seria necessário acessar o BD.
2-Atomicidade - sua aplicação não fica dividida, toda a lógica fica nela.
3-Migração - ao usar funções nativas de um determinado BD para construir sua lógica pode ser que em outro BD esta funçãoes não sejam as mesmas. Isto dificulta a migração para outro BD e hoje é impoortante que as aplicações funcionem em qualquer bacno de dados.
Annotations são um forma que por exemplo o .Net MVC 5 permite adicionar consistências e validações na propria classe.
public string Title { get; set; } [Required(ErrorMessage = "Price is required")] [Range(0.01, 100.00, ErrorMessage = "Price must be between 0.01 and 100.00")
GOSTEI 0
Mariana Carvalho
10/03/2015
Seria o mais correto, o que está sendo utilizado atualmente como "melhores praticas" não é?
GOSTEI 0