2014-06-18 57 views
1

我試圖在具有以下更新觸發器的表執行更新,但我收到以下錯誤:更新觸發錯誤

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

這裏是觸發...

如果photoRatingID的值設置爲NULL則刪除記錄,從另一個表

IF UPDATE(photoRatingID) 
BEGIN 
    IF (SELECT photoRatingID FROM inserted) IS NULL 
     BEGIN 
      DELETE mbr_Media_Approval_Primary 
      FROM deleted, mbr_Media_Approval_Primary 
      WHERE deleted.mbrID = mbr_Media_Approval_Primary.mbrID 
     END 
END 

中的所有表包含唯一的ID「mbrID」

+1

記住多行能一次插入或更新 - 觸發器需要執行基於集合的操作。 – StuartLC

+0

@StuartLC他可以使用遊標並在基於程序的操作中執行遊標。但我同意基於集合的操作是更好的方式:) – codemonkey

+0

是的,你會發現沒有多少人喜歡使用[遊標]的想法(http://stackoverflow.com/questions/58141/why- [Sql Server](http://stackoverflow.com/questions/287445/why-do-people-hate-sql-sql-server-sql-server-sql-services-sql-servers-in-sql-server)遊標等等),還有一個觸發器... – StuartLC

回答

1

您的SELECT photoRatingID FROM inserted返回多行,如錯誤消息所示。因此IS NULL比較無法正常工作。您可以將您或多或少必要的方法來一套基礎的方法是這樣的:

IF UPDATE(photoRatingID) 
BEGIN 
    DELETE map 
    FROM mbr_Media_Approval_Primary map 
     JOIN deleted d ON d.mbrID=map.mbrID 
     JOIN inserted i ON i.mbrID=d.mbrID 
    WHERE i.photoRatingID IS NULL 
END 
+0

這是否會在每一行更新(低性能)上執行查找?僅當值設置爲NULL時纔想執行查找 –

+0

取決於數據和更新集。如果擔心性能 - 你不會用遊標,循環或其他東西擊敗聲明性查詢。數據庫管理系統的目的是選擇最好的策略來完成查詢。 –

+0

不幸的是我同意@Martin K. :)但是看看這兩者之間的性能真正的區別是很有趣的。 – codemonkey

0

對於這樣的邏輯,你可以使用下面的光標例如:

IF UPDATE(photoRatingID) 
BEGIN 
    DECLARE @photoRatingID AS int; 
    DECLARE KURSOR_photoRating CURSOR FOR 
     SELECT photoRatingID FROM inserted; 
    OPEN KURSOR_photoRating;  
    FETCH NEXT FROM KURSOR_photoRating INTO @photoRatingID 
    WHILE @@FETCH_STATUS = 0 
    BEGIN  
     IF (@photoRatingID IS NULL) 
     BEGIN    
      DELETE mbr_Media_Approval_Primary 
      FROM deleted, mbr_Media_Approval_Primary 
      WHERE deleted.mbrID = mbr_Media_Approval_Primary.mbrID   
     END 
     FETCH NEXT FROM KURSOR_photoRating INTO @photoRatingID 
    END 
    CLOSE KURSOR_photoRating;  
    DEALLOCATE KURSOR_photoRating; 
END