SQL Server:如果没有约束错误,则删除行

时间:2015-10-16 23:02:20

标签: sql sql-server ssms

比这复杂得多,但这是基本的

  • Person表(id,name,emailaddress)
  • Salesperson table(id,personID)
  • CustomerServiceRep table(id,personID)

Jeff是personID = 1的销售人员(id = 4)和customerservicerep(id = 5)。

简单

Trigger on SalesPerson Table 
AFTER DELETE
AS
    DECLARE @personID int = (SELECT personID FROM deleted);

    IF @personID IS NOT NULL
    BEGIN TRY
         DELETE FROM Person 
         WHERE Person.id = @personID;
    END TRY
    BEGIN CATCH
    END CATCH

DELETE FROM SalesPerson WHERE id=4; 

原因

  

Msg 3616,Level 16,State 1   触发器执行期间出错。批处理已中止,用户事务(如果有)已回滚。

我确信如果某种约束存在personID,则有一种更简单的方法可以不删除Private Sub Tab3_Plan_Enter(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles Tab3_Plan.Enter dgPlan.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells CircuitItems = LoadCatalogItems(dgPlan, cbVDSvcLocation, iKind.PlanSku) ' More event code Private Function LoadCatalogItems(ByRef DGV As DataGridView, _ ByVal cbControl As System.Windows.Forms.ComboBox, _ ByRef ItemKind As Integer) As Integer Dim DescDGName As String Dim OrigInternalDesc As String Dim DisplayDesc As String DGV.Rows.Clear() ' <-- This is where the exception is thrown ' More function code 。或者赶上约束。如果有更多的表/列可能使用相同的表/约束(外键),那么浏览每个可能存在的表似乎非常重复并且可能更难。

2 个答案:

答案 0 :(得分:0)

这里需要一个而不是删除触发器而不是后触发器。

CREATE Trigger tr_Delete_person 
on Person 
INSTEAD OF DELETE
AS
BEGIN
   SET NOCOUNT ON;

-- Delete any child records 

    Delete FROM SalesPerson 
    WHERE EXISTS (SELECT 1 FROM deleted 
                  WHERE personID = SalesPerson.personID)


    Delete FROM CustomerServiceRep  
    WHERE EXISTS (SELECT 1 FROM deleted 
                  WHERE personID = CustomerServiceRep .personID)


-- Finally delete from the person table 
    DELETE FROM Person 
    WHERE EXISTS (SELECT 1 FROM deleted 
                  WHERE personID = Person .personID)


END

答案 1 :(得分:0)

你的触发器中也有一个根本的缺陷,因为你似乎期望触发器将被激活每行一次 - 这是 NOT 在SQL Server中的情况。相反,触发器会在每个语句时触发,而伪表Deleted可能包含多行

鉴于该表可能包含多行 - 您希望在这里选择哪一行?

DECLARE @personID int = (SELECT personID FROM deleted);

未定义 - 您将从Deleted中的一行,任意行中获取值,而忽略所有其他行 - 通常你想要什么!

您需要使用Deleted WILL 包含多行的知识重写整个触发器!您需要使用基于集合的操作 - 不要只期望Deleted中的一行!