Deletado em 23 de maio de 2009

DELETE com INNER JOIN

Olá pessoal.

Hoje quero jogar fora um mito no MS SQL Server, esse mito está relacionado à instrução DELETE.

Existe DELETE com INNER JOIN no MS SQL... Repito, no MS SQL???

Não... Ou melhor... Sim... Ou melhor... Bom, existe, mas acho que não funciona da maneira que gostaríamos que funcionasse hehe.

Vamos ao seguinte cenário.

Temos uma tabela de usuários e uma tabela que faz a relação do usuário com as empresas. Uma relação N pra N normalizada onde um usuário pode ter relação com N empresas e uma empresa pode estar relacionada com N usuários.

Eu quero deletar o usuário 1 da tabela MailerUsuario.

DELETE FROM MailerUsuarios WHERE UserId = 1

Ops… Isso não é possível

A instrução DELETE conflitou com a restrição do REFERENCE "FK_MailerUserEmpresa_MailerUsuarios".
O conflito ocorreu no banco de dados "Mailer", tabela "dbo.MailerUserEmpresa", coluna 'UserId'. A instrução foi finalizada.

Isso estava previsto. Não podemos deletar um usuário que tem referencia em uma outra tabela. Mas como vamos deletar esse usuário?

“Oras Bolas”, vamos juntar as tabelas e mandar pau nelas =)

DELETE FROM MailerUserEmpresa MUE INNER JOIN     MailerUsuarios MU ON MUE.UserId = MU.UserId WHERE MUE.UserId = 1

É... Assim não funciona =(, Ahhhh!!! vamos tentar igual no MY SQL

DELETE MailerUserEmpresa, MailerUsuarios FROM MailerUserEmpresa MUE INNER JOIN     MailerUsuarios MU ON MUE.UserId = MU.UserId WHERE MUE.UserId = 1

#@$=(!%, também não funcionou… Devo estar digitando alguma coisa errada… Mas o que??? Vou deixar só uma tabela antes do FROM.

DELETE MailerUserEmpresa FROM MailerUserEmpresa MUE INNER JOIN     MailerUsuarios MU ON MUE.UserId = MU.UserId WHERE MUE.UserId = 1 (4 linha(s) afetadas)

Eeeeeee funcionou!!! Mas será que deletou mesmo???

Sim, mas não como eu gostaria...

A instrução DELETE não consegue deletar registros em tabelas diferentes ao mesmo tempo no MS SQL. A minha instrução com INNER JOIN funcionou, mas o que ela fez foi deletar da tabela MailerUserEmpresa os registros 1 que também existiam na tabela MailerUser.

Se não tivessemos colocado o WHERE, teria deletado todos os registros que existiam ligação entre uma tabela e outra... Neste caso deletaria todos, mas em outros casos, de 3 ou mais tabelas, seria até bem utilizavél.

Mas e agora, como vou deletar os meus registros das duas tabelas???

Muito simples, basta deletar primeiro as de chave estrangeira e depois as de chave primária.

DELETE FROM MailerUserEmpresa WHERE UserId = 1

DELETE FROM MailerUsuario WHERE UserId = 1

É realmete, isso é um lixo huahuahuahua deveria estar aqui mesmo!

Até a próxima.

Deletado em 4 de maio de 2009

Validações de Dados no C#

Frequentemente precisamos fazer validações em dados providos de usuários. Geralmente essas validações são por meio de linguagens client script como o JavaScript.

Porém, e se quisermos fazer essas validações no C#, deixando o trabalho para o servidor? Como saber se o dado de input do usuário é do tipo que esperamos?

Podemos, para solucionar essas questões, utilizar o método TryParse dos tipos de dados. Esse método existe na maioria dos tipos de dados nativos do C#.

Esse método, como o próprio nome já diz, tenta dar um Parse em uma string para o valor a qual o método é chamado. Se o Parse for realizado com sucesso ele retorna o valor para uma variável do mesmo tipo.

Vamos criar um método para verificar se meu tipo de dado realmente é um inteiro:

public bool IsInteiro(string Valor, out int Resultado)
{
    return int.TryParse(Valor, out Resultado);
}

O Método fica muito simples, recebe o valor que será testado e outro valor que será a saída, caso o resultado for um realmente um inteiro.

Para testar, no nosso Page Load vamos fazer a validação:

protected void Page_Load(object sender, EventArgs e)
{
    int numI;

    Response.Write((IsInteiro("5", out numI)) ? numI.ToString() : "Não é um Inteiro");
}

Neste caso, seria exibido o número 5 normalmente. Se alterarmos o “5” para “5aa” seria exibido a mensagem “Não é um Inteiro”.

Poderíamos validar, como disse antes, outros tipos de dados, como o DateTime por exemplo:

public bool IsData(string Valor, out DateTime DataResult)
{
    return DateTime.TryParse(Valor, out DataResult);
}

Assim, aprimorando nossa validação:

protected void Page_Load(object sender, EventArgs e)
{
    int numI;
    DateTime data;

    Response.Write((IsInteiro("5", out numI)) ? numI.ToString() : "Não é um Inteiro");
    Response.Write((IsData("30/02/2009", out data)) ? data.ToString() : "Não é um Data valida");
}

Onde, neste caso, seria exibida a mensagem "Não é um Data valida".

Conclui-se que podemos fazer verificações de dados em qualquer linguagem, e no C# não é diferente, basta o desenvolvedor ver qual ação apropriada para seu projeto e utilizá-la do modo mais simples e reutilizável possível.

Abraços, até a próxima!

Topo