避免SQL Server中的数据库游标
我有一点困惑(至少对我来说),我希望这主要是因为我还不是宇宙的SQL大师。基本上我有三张桌子: 表A、表B和表C 表C与表B之间有一个FK(外键),表B与表a之间有一个FK(每一个都是多对一) 我需要从表A中删除一个条目,当然也要从表B和表C中删除所有对应的条目。在过去,我使用光标来完成这项工作,选择表B中的所有条目,并在每个条目之间循环以删除表C中的所有对应条目。现在,这项工作正常,但我怀疑/希望有一种更好的方法可以在不使用游标的情况下实现这一效果。所以这就是我的问题-我如何不用光标来做这件事,或者可以做到避免SQL Server中的数据库游标,sql,sql-server,tsql,cursors,Sql,Sql Server,Tsql,Cursors,我有一点困惑(至少对我来说),我希望这主要是因为我还不是宇宙的SQL大师。基本上我有三张桌子: 表A、表B和表C 表C与表B之间有一个FK(外键),表B与表a之间有一个FK(每一个都是多对一) 我需要从表A中删除一个条目,当然也要从表B和表C中删除所有对应的条目。在过去,我使用光标来完成这项工作,选择表B中的所有条目,并在每个条目之间循环以删除表C中的所有对应条目。现在,这项工作正常,但我怀疑/希望有一种更好的方法可以在不使用游标的情况下实现这一效果。所以这就是我的问题-我如何不用光标来做这件事
(如果我不清楚,请告诉我-我会设法解决这个问题).将您的
外键声明为删除级联上的当您为两个表创建外键关系时,您可以在删除级联上指定,当您删除a中的记录时,它将为您解决此问题。您可以通过两种方式完成此操作
- 你可以用外键
- 您可以在每个表上使用delete触发器来删除相关记录
- 如果您使用的是MS SQL server,还可以使用触发器。在本例中,您将仅在TableA上创建触发器,并在触发器中放入所有逻辑以删除所有3个表中的记录
在上述任何一种情况下,您只需从表A中删除记录,并让级联和触发器处理其余的记录。已经给出的答案(级联删除和触发器)非常好,但您可能会在不具备这些选项的环境中工作。如果是这样,下面是一个纯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)
@OP-当删除表a中的引用记录时,这将删除表B和C中的所有记录
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
--
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)