Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

FabianoSouza

Delete INNER JOIN não funciona

Recommended Posts

Vi em vários lugares que essa estrutura funciona para excluir dados da tabela "X" e da tabela que tiver registros associados a ela.

No meu caso é para excluir um registro da tabela de cursos e todos os registros associados na tabela de módulos

DELETE tabCURSOS
FROM tabCURSOS AS C INNER JOIN Modulos AS M
ON C.SisCursoCod = M.ModulosCodCurso
WHERE C.SisCursoCod = '1' 

Está excluindo apenas os registros pais, na em tabCURSOS.

 

Está faltando algo? Será que tem a ver com permissão na tabela filha?

 

Obrigado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não corre msg de erro.

Mas o objetivo não é atendido, que seria excluir o item da tab principal e os itens relacionados na segunda tabela.

 

Só está excluindo o item principal.

 

Até tentei assim

DELETE tabCURSOS
FROM tabCURSOS AS C INNER JOIN Modulos AS M
ON C.SisCursoCod = M.ModulosCodCurso
WHERE C.SisCursoCod = '1' AND M.ModulosCodCurso = '1' (informando a chave estrangeira da segunda tab)

Mas tb não funciona

Compartilhar este post


Link para o post
Compartilhar em outros sites

Esse delete apagará apenas os registros da tabCURSOS, vamos pensar na lógica da query.

Na query será listados os cursos que estiverem na tabela Modulos (cursos sem modulo serão desprezados) e depois esses cursos serão deletados. O join serve apenas para forçar os cursos que tiverem modulos e não para apagar dados da tabela Modulos.

A solução para o seu caso seria pegar todos os M.ModulosCodCurso do resultado desse delete (antes de deletar senão você perderá a referencia) e deletá-los na Modulos também.

Existem várias maneiras de fazer isso, te mostrarei a mais simples e de fácil entendimento.

SELECT C.SisCursoCod as chave
into #deletar
FROM tabCURSOS AS C INNER JOIN Modulos AS M
ON C.SisCursoCod = M.ModulosCodCurso
WHERE C.SisCursoCod = '1' AND M.ModulosCodCurso = '1' (informando a chave estrangeira da segunda tab)

GO

DELETE tabCURSOS
FROM tabCURSOS AS C INNER JOIN #deletar AS D
ON C.SisCursoCod = D.chave

GO

DELETE M.ModulosCodCurso
FROM Modulos as M INNER JOIN #deletar AS D
ON M.ModulosCodCurso = D.chave

Repito, há outras formas de fazer isso e eu mesmo não faria assim porque sempre que trabalho com Update, Insert e Delete eu inicio uma transação com o BEGIN TRANSACION, executo a query, confiro se o resultado foi o esperado e depois confirmou ou cancelo (COMMIT ou ROLLBACK), crie o hábito de fazer isso também pois evita muitos transtornos.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Legal, Hugo. Vou testar sua sugestão.
Mas diga uma coisa. Preciso rodar a query numa aplicação (ASP).
A pergunta é: Consigo "portar" querys com "BEGIN TRANSACION", COMMIT ou ROLLBACK para a aplicação?

 

Valew

Compartilhar este post


Link para o post
Compartilhar em outros sites

Hugo,

Estava ocorrendo um erro "Erro Nome de objeto 'M.ModulosCodCurso'" mas resolvi...

Bom, rodei a consulta e realmente excluiu os dados como preciso.

Mas tenho duas dúvidas.

 

1) O que significa o #deletar?

 

2) Quando executo (pelo SQLServer Management Studio) uma segunda vez, recebo a msg "Já existe um objeto com nome '#deletar' no banco de dados." Será que terei esse erro quando rodar a consulta pela aplicação?

 

 

Obrigado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

#deletar é uma tabela temporária, essa tabela existirá enquanto a sessão que a criou estiver aberta, depois que você fechar a sessão a tabela será destruída. Quando você roda a query a primeira vez a tabela é criada, se executar a segunda vez na mesma sessão vai dar erro porque a tabela já existe, para executar a segunda vez sem dar esse erro inclua essa linha no começo da query.

IF object_id('tempdb..#deletar') IS NOT NULL 
BEGIN
     DROP TABLE #deletar
END

Explicando a query num todo:
Primeiro foi feito um select para buscar os dados que você precisa e amarzená-lo numa tabela temporária, depois um delete na tabCURSOS usando os dados que ficaram guardados na temporária e por ultimo outro delete, agora na ModulosCodCurso.

Pelo pouco conhecimento que tenho com o ASP sei que é perfeitamente possível usar Begin Transaction, mas para te dizer como isso é feito eu não sei, teria que consultar a documentação da linguagem para saber como a query ficaria.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.