Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
避免SQL Server中的数据库游标_Sql_Sql Server_Tsql_Cursors - Fatal编程技术网

避免SQL Server中的数据库游标

避免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中的所有对应条目。现在,这项工作正常,但我怀疑/希望有一种更好的方法可以在不使用游标的情况下实现这一效果。所以这就是我的问题-我如何不用光标来做这件事

我有一点困惑(至少对我来说),我希望这主要是因为我还不是宇宙的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)