我更喜欢 没有
自动级联操作,无论是DELETe还是UPDATE。只是为了省心。想象一下,您已经配置了级联删除,然后由于某些错误而试图删除错误的用户,即使数据库中有与之相关的数据,您的程序也会被删除。相关表中的所有相关数据都将消失,而不会发出任何警告。
通常,我确保首先使用明确的单独过程删除所有相关数据,每个相关表一个,然后再删除主表中的行。删除将成功,因为在引用表中没有子行。
对于您的示例,我将有一个
DeleteUser带有一个参数的专用存储过程
UserID,该存储过程知道哪些表与用户相关,并且应按什么顺序删除详细信息。此过程经过测试,是删除用户的唯一方法。如果程序的其余部分错误地尝试直接从
Users表中删除行,那么如果相关表中有一些数据,则此尝试将失败。如果错误删除的用户没有任何详细信息,则尝试会进行,但是至少您不会丢失很多数据。
对于您的架构,过程可能如下所示:
CREATE PROCEDURE dbo.DeleteUser @ParamUserID intASBEGIN SET NOCOUNT ON; SET XACT_ABORT ON; BEGIN TRANSACTION; BEGIN TRY -- Delete from CollectedItems going through Items DELETe FROM CollectedItems WHERe CollectedItems.itemId IN ( SELECt Items.id FROM Items WHERe Items.userId = @ParamUserID ); -- Delete from CollectedItems going through Collections DELETe FROM CollectedItems WHERe CollectedItems.collectionId IN ( SELECt Collections.id FROM Collections WHERe Collections.userId = @ParamUserID ); -- Delete Items DELETE FROM Items WHERe Items.userId = @ParamUserID; -- Delete Collections DELETE FROM Collections WHERe Collections.userId = @ParamUserID; -- Finally delete the main user DELETE FROM Users WHERe ID = @ParamUserID; COMMIT TRANSACTION; END TRY BEGIN CATCH ROLLBACK TRANSACTION; ... -- process the error END CATCH;END
如果您真的想设置级联删除,那么我将只为表定义 一个触发器
Users。同样,将没有外键具有级联删除功能,但是
Users表上的触发器将具有与上述过程非常相似的逻辑。



