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.

6 comentários:

Anônimo disse...

Finalmente encontrei !!!
Caraca !!
Os artigos que eu encontrei sobre o comando DELETE estavam todos errados....
A galera não sabe e posta qq. coisa.

Valeu Adriano !!

Anônimo disse...

Ao inves do inner utilizem o IN()

Adriano disse...

Não entendi o usu do IN() para deletar informações de duas tabelas ao mesmo tempo...

Anônimo disse...

Não faz sentido você fazer um delete com join e deletar de todas as tabelas.
o join só te retorna a relação que será deletada na tabela que você especificou depois da clausula from.
Imagina a desgraça que aconteceria se você excluísse de todas as tabelas que você fez no join?Você que está com o conceito errado sobre um inner join numa Clausula delete


Quanto ao IN()

DELETE MailerUserEmpresa
where fk in (select pk from MailerUsuarios WHERE UserId = 1)

Anônimo disse...

Já ouviu falar de cascade delete?

Anônimo disse...

Muito boa explicação.
Obrigado.

Repassando

Postar um comentário

Jogue sua opinião na lixeira!

Topo