2009-09-28 82 views
5

我希望主要是因为我还不是宇宙的SQL主人,所以我有一个难题(至少对我来说)。基本上我有三个表:SQL Server中避免数据库光标

表A,表B和表C.

表C具有FK(Foriegn密钥)表B,其具有FK表A.(每个这些被许多到一)

我需要从表A中删除一个条目,当然还要从表B和C中删除它的所有相应条目。在过去,我使用了一个游标来完成此操作,选择了表B中的所有条目并循环遍历每一个删除表C中的所有相应的条目。现在这个工作 - 并一直工作正常,但我怀疑/希望有一个更好的方式来实现这种效果,而不使用游标。所以这就是我的问题 - 我如何在不使用游标的情况下做到这一点,或者可以做到这一点?

(请让我知道如果我不清楚 - 我会试着解决这个问题)。

回答

11

声明你FOREIGN KEY S作为ON DELETE CASCADE

+3

@ OP-当表A中删除引用记录时,这将删除表B和C中的所有记录 – 2009-09-28 14:16:47

2

当您创建两个表可以指定ON DELETE CASCADE的外键关系,当你在A.删除记录它会照顾这对你

8

你可以这样做一对夫妇的方式...

CREATE TABLE TableB 
    (FKColumn INT, 
    CONSTRAINT MyFk FOREIGN KEY (FKColumn) 
     REFERENCES TableA(PKColumn) ON DELETE CASCADE) 
  • 你可以使用每个表中删除触发器删除相关记录。

CREATE TRIGGER cascade_triggerA 
    ON TableA 
    FOR DELETE 
AS 
BEGIN 

    DELETE TableB 
    FROM TableB JOIN DELETED ON TableB.FKColumn = DELETED.PKColumn 

END 

CREATE TRIGGER cascade_triggerB 
    ON TableB 
    FOR DELETE 
AS 
BEGIN 

    DELETE TableC 
    FROM TableC JOIN DELETED ON TableC.FKColumn = DELETED.PKColumn 

END 
  • 如果您使用MS SQL服务器,你也可以使用INSTEAD OF DELETE触发器。在这种情况下,您只需在TableA上创建触发器 - 并在触发器中将所有逻辑从所有3个表中删除记录。

在上述任何情况下,您只需从表A中删除记录,并让级联和触发器负责其余部分。

5

已经给出的答案(级联删除和触发器)非常好,但是您可能在这些不是选项的环境中工作。如果是这样,下面是一个纯粹的SQL解决方案。该示例仅关注DELETE语法。在现实世界中,您可能会将其封装在一个事务中,并将其作为存储过程来实现。

-- 
DECLARE @Param_PK_TableA int 
SET  @Param_PK_TableA = 1500 


------------------------------- 
-- TABLE C -------------------- 
DELETE TableC 

FROM TableC 

    INNER JOIN TableB 
      ON TableB.TableB_ID = TableC.TableB_ID 

    INNER JOIN TableA 
      ON TableA.TableA_ID = TableB.TableA_ID 

WHERE 
    (TableA.TableA_ID = @Param_PK_TableA) 



------------------------------- 
-- TABLE B -------------------- 
DELETE TableB 

FROM TableB 

    INNER JOIN TableA 
      ON TableA.TableA_ID = TableB.TableA_ID 

WHERE 
    (TableA.TableA_ID = @Param_PK_TableA) 



------------------------------- 
-- TABLE A -------------------- 
DELETE TableA 

WHERE 
    (TableA.TableA_ID = @Param_PK_TableA)