Array
(
    [0] => stdClass Object
        (
            [Votos_Balanceados] => 1
            [id] => 513784
            [titulo] => Validação de CPF e CNPJ
            [dataCadastro] => DateTime Object
                (
                    [date] => 2015-03-16 14:35:33
                    [timezone_type] => 3
                    [timezone] => America/Sao_Paulo
                )

            [isFirstPost] => -1
            [idUsuario] => 418027
            [status] => A
            [isExample] => 
            [NomeUsuario] => Jothaz
            [Apelido] => 
            [Foto] => 418027_20150313165406.jpg
            [Conteudo] => 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:

[code]
/*
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

[/code]

CNPJ:

[code]
/*
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

[/code] ) )

Validação de CPF e CNPJ

Mariana Carvalho
   - 10 mar 2015

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?

Post mais votado

Jothaz
   - 16 mar 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:

#Código

/* 
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:

#Código
/* 
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 

Mariana Carvalho
   - 16 mar 2015

???????????????

Thiago Santana
   - 16 mar 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"

Mariana Carvalho
   - 20 mar 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.

Jothaz
   - 20 mar 2015


Citação:
É 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.

Mariana Carvalho
   - 20 mar 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.

Aspnet Mvc
   - 22 mai 2015

Acho que voce precisa usar data annotation

Aspnet Mvc
   - 22 mai 2015

Mas no caso eu estou desenvolvendo com code first então trato disto dentro da aplicação mesmo

Thiago Santana
   - 22 mai 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.

Mariana Carvalho
   - 22 mai 2015


Citação:
Acho que voce precisa usar data annotation


Me explique o é o data annotation, por favor.

Mariana Carvalho
   - 22 mai 2015


Citação:
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.

Jothaz
   - 22 mai 2015


Citação:

Citação:
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.
#Código

        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")

Mariana Carvalho
   - 22 mai 2015

Seria o mais correto, o que está sendo utilizado atualmente como "melhores praticas" não é?