SQL:如何删除子表的子表?

时间:2012-07-12 16:19:48

标签: sql

我有3张桌子,USERS,CHATBOX,IMAGEBOARD。用户可以拥有(0,N)聊天框,聊天框可以拥有(0,1)图像板。我需要删除一个用户。所以我需要在聊天框之前删除图像板,在用户之前删除聊天框。请求是什么?!

这是我的架构的图像:

Table Schema

3 个答案:

答案 0 :(得分:3)

我会使用这样的模式:

BEGIN TRANSACTION

BEGIN TRY
  -- delete statements here.
END TRY

COMMIT TRANSACTION;

BEGIN CATCH
  ROLLBACK TRANSACTION;
END CATCH

删除语句如下所示: (我不做mysql太多借口小错误)

CREATE TEMPORARY TABLE IMAGELIST (
-> ID INT NOT NULL
)

SELECT C.FK_IMAGEBOARD AS ID
FROM CHATBOX C
INTO IMAGELIST
WHERE C.FK_USERNAME = @USERNAME

DELETE FROM CHATBOX WHERE FK_USERNAME = @USERNAME;

DELETE FROM IMAGEBOARD WHERE ID IN
  (SELECT ID FROM IMAGELIST)

DELETE FROM USERS WHERE USERNAME = @USERNAME;

答案 1 :(得分:3)

由于您的聊天框中有对图像板的引用,因此您无法删除聊天框,因为该图像板的链接将丢失(所有剩余的图像板中您不知道哪个图像板属于已删除的聊天框。

但您无法从imageboard表中删除,因为它是从聊天室表中引用的。如果imagebox表包含对chatbox表的引用,事情会更容易。

如果还可以删除任何不再使用的图像板,则以下内容应该有效:

delete from chatbox
where fk_username = 'foobar';

delete from imageboard
where not exists (select 1 from chatbox where imageboard.id = chatbox.fk_imagebox);

delete from users 
where username = 'foobar';

commit;

另一个选项是延迟外键,然后您可以在从chatbox表中删除之前从imageboard表中删除,因为延迟约束是在提交时评估的,而不是在运行实际的delete语句时。 PostgreSQL和Oracle中提供了延迟约束。

答案 2 :(得分:1)

on delete cascadeusers表中添加chatbox条件。这样你就不必做任何事了。如果您删除用户,数据库将删除您的条目。

您可以找到MySQL here

的示例