2012-05-02 61 views
0

我有一个表大学和一个表城市。他们之间有一个m:n的关系,所以关系被保存在一个名为CityUniversities的表格中。现在我想编写一个触发器,删除大学和大学之间的表格之间的所有关系。但它不起作用。对于删除触发器不起作用(Microsoft SQL Server Management Studio)

“消息547,级别16,状态0,2号线 DELETE语句冲突与基准约束‘FK_CityUniversities_Universities’。该冲突发生于数据库” Alumni_Dev:试图删除大学的时候,我总是收到以下错误信息“,表”dbo.CityUniversities“,列'UniversityId'。 该声明已被终止。”

这是我所实施并成功地执行了触发条件(表大学):

USE [Alumni_Dev] 
GO 
/****** Object: Trigger [dbo].[deleteUni] Script Date: 05/02/2012 11:42:43 ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER TRIGGER [dbo].[deleteUni] 
ON [dbo].[Universities] 
FOR DELETE 
AS 
DECLARE @UniId int 
SELECT @UniId = (SELECT UniversityId FROM deleted) 
BEGIN 
--Remove constraints 
DELETE FROM dbo.CityUniversities WHERE UniversityId = @UniId; 
END 

我已经比我有几个参考解决方案,但是我无法找到任何可能是错误的。是否在受影响的表格中有任何错误的设置?

我很乐意听到任何建议。


我终于解决了我的问题有以下触发(感谢尼古拉):

ALTER TRIGGER [dbo].[deleteUni] 
ON [dbo].[Universities] 
INSTEAD OF DELETE 
AS 
DECLARE @UniId int 
SELECT @UniId = UniversityId FROM deleted 
BEGIN 
--Remove constraints 
DELETE FROM dbo.CityUniversities WHERE UniversityId = @UniId; 
DELETE FROM dbo.Universities WHERE UniversityId = @UniId; 
END 

回答

4

触发不能用于其它表删除孤立的记录,因为触发器被执行在检查约束之前。您应该设置ON DELETE CASCADE

如果您想在删除前执行一些检查,但是不要忘记在触发器末尾添加delete Universities where ...以实际删除记录,您也可以使用INSTEAD OF触发器。

两个有关触发器点:

  • 在触发器主体的开头添加SET NOCOUNT ON避免内部触发SQL语句改变“行受到影响”,你可能需要调用代码值的posibility,
  • 不要将删除和插入的表视为只包含一条记录。当您尝试删除两所大学时会有令人讨厌的惊喜。你还是你一起共事与删除或插入表一表,使用它们作为过滤器,或使用存在:

    delete dbo.CityUniversities 
        from dbo.CityUniversities 
    inner join deleted 
        on dbo.CityUniversities.UniversityId = deleted.UniversityId 
    

delete dbo.CityUniversities 
where exists (select null 
       from deleted 
       where deleted.UniversityId =dbo.CityUniversities.UniversityId) 

哦,

SELECT @UniId = (SELECT UniversityId FROM deleted) 

相当于:

SELECT @UniId = UniversityId FROM deleted 
+0

Thx,详细的答案。 – user1335772

相关问题