5

我有一点困惑(至少对我来说),我希望这主要是因为我还不是宇宙的 SQL 大师。基本上我有三个表:

表 A、表 B 和表 C。

表 C 对表 B 有一个 FK(外键),表 B 对表 A 有一个 FK。(每个都是多对一)

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

(如果我不清楚,请告诉我 - 我会尝试解决这个问题)。

4

4 回答 4

11

FOREIGN KEY将你的 s声明为ON DELETE CASCADE

于 2009-09-28T14:14:25.187 回答
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 中删除记录,然后让级联和触发器处理其余的事情。

于 2009-09-28T14:16:05.200 回答
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)
于 2009-09-28T15:29:59.713 回答
2

当您为两个表创建外键关系时,您可以指定 ON DELETE CASCADE,它会在您删除 A 中的记录时为您处理此问题。

于 2009-09-28T14:15:29.023 回答