避免SQL Server中的数据库游标

Str*_*lin 5 sql t-sql sql-server cursors

我有一点想法(至少对我而言),我希望这主要是因为我还不是宇宙的SQL大师.基本上我有三张桌子:

表A,表B和表C.

表C具有表B的FK(Foriegn Key),其具有表A中的FK.(每个都是多对一)

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

(如果我不清楚,请告诉我 - 我会尽力解决问题).

Qua*_*noi 11

宣告你的FOREIGN KEYs为ON DELETE CASCADE

  • @ OP-当表A中删除引用的记录时,这将删除表B和C中的任何记录 (3认同)

Sco*_*vey 8

你可以用两种方式做到这一点......

CREATE TABLE TableB
    (FKColumn INT,
     CONSTRAINT MyFk FOREIGN KEY (FKColumn) 
         REFERENCES TableA(PKColumn) ON DELETE CASCADE)
Run Code Online (Sandbox Code Playgroud)
  • 您可以在每个表上使用删除触发器来删除相关记录.

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
Run Code Online (Sandbox Code Playgroud)
  • 如果您正在使用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)
Run Code Online (Sandbox Code Playgroud)