【发布时间】:2019-12-10 23:50:03
【问题描述】:
所以我有这张桌子:
ID Name IsDeleted
1 test True
2 test2 False
我目前有以下触发器:
CREATE TRIGGER [dbo].[Trigger_test_IsDeleted]
ON [dbo].[test]
INSTEAD OF DELETE
AS
BEGIN
SET NOCOUNT ON;
UPDATE dbo.test
SET IsDeleted = 1
WHERE ID = 1;
END
当我单击索引视图中某行上的删除按钮时,我需要启动此触发器并将该行上的 IsDeleted 设置为 1(或 True)。但是,使用上述触发器执行此操作显然只会删除 ID = 1 的行源。如果我省略 WHERE 语句,它会将所有行的 IsDeleted 设置为 true。
我需要我的触发器来动态确定“删除”被按下的位置,并且只删除该行。
我知道在 MySQL 中,您可以通过在删除触发器中使用以下内容来完成此操作:
SET new.IsDeleted = 1
有没有办法获得与“新”相同的效果。在 SQL Server 触发器中?
既然我们在讨论这个话题,我想实现同样的目标,但要更改控制器中的当前代码。这是它现在的样子:
//POST - Delete
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Delete(int? id)
{
var test = await _db.Test.FindAsync(id);
if (test== null)
{
return View();
}
_db.Test.Remove(test);
await _db.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
这段代码将实现对数据库的普通删除操作。我想将其更改为将“IsDeleted”设置为 1 而不是删除记录。
【问题讨论】:
-
为什么不直接从您的代码中执行
UPDATE命令而不是发出DELETE并假设触发器将始终启用?这是一个危险的假设,因为触发器通常在维护操作期间被禁用,如果有人忘记重新启用触发器,您会很高兴恢复数据。 -
如果需要使用触发器,请查看inserted and deleted 伪表上的文档。
-
@Dai,我认为即使有人从应用程序外部删除该行,他们也想标记已删除的记录而不是实际删除。但是你的观点也是有效的。
-
@Dai 是的,自从发布问题以来我一直在考虑这个问题,我认为(从调试的角度来看)在我的代码中更改控制器上的删除方法会更好。只是我目前更习惯触发,所以我的问题是基于我的舒适区。此外,我想在我的数据库中强制执行我的业务逻辑以保护它,以防在其上构建新的前端。如果可以的话,我可能会在触发器和控制器上强制执行它,但这可能会导致冲突。
标签: sql-server asp.net-mvc model-view-controller database-trigger