2013-11-26 4 views
0

어떻게 여러 행을 업데이트 트리거로 처리 할 수 ​​있습니까/현재 트리거를 수정하여 현재 동작을 수행하는 방법은 무엇입니까? 나는 단지 하나의 행이 위대한 작품을 업데이트하지만 같은 시간에 여러 행을 업데이트하면 나는 오류가 발생하는 경우 :SQL 트리거 업데이트에서 여러 행 처리

Msg 512, Level 16, State 1, Procedure TriggerUpdateAdvert, Line 9
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

이 내 트리거입니다 :

ALTER TRIGGER dbo.TriggerUpdateAdvert 
ON dbo.Advert FOR UPDATE 
AS 
    DECLARE @OldStatus INT; 
    DECLARE @NewStatus INT; 
    DECLARE @ID UNIQUEIDENTIFIER; 

    SET @ID=(SELECT I.ID_Advert FROM INSERTED I); 
    PRINT @ID 
    SET @OldStatus=(SELECT D.Status FROM DELETED D WHERE [email protected]); 
    SET @NewStatus=(SELECT I.Status FROM INSERTED I WHERE [email protected]); 


    IF(@[email protected]) 
    BEGIN 
    print @OldStatus 
    print @NewStatus 
     IF(@NewStatus=1 or @NewStatus=3) 
     BEGIN 
      UPDATE Advert SET Published_Date=GETDATE() WHERE [email protected] 
     END 
    END 


GO 

편집 : 내가 만든

다음 코드 :

 UPDATE A 
     SET A.Published_Date=GETDATE() 
     FROM Advert A 
     INNER JOIN Inserted I ON A.ID_Advert=I.ID_Advert 
     INNER JOIN Deleted D ON D.ID_Advert=A.ID_Advert 
     WHERE I.Status!=D.Status AND (I.Status IN (1,3) AND D.Status NOT IN (1,3)) 

의견이 있으십니까?

+1

귀하의 ** 주요 결함은 ** 트리거는 사용자가 가정 것을 호출 할 것입니다 ** 번 행 ** 당 - 그것의 **하지 **! 그것은 ** ** 한 번 명령문 **라고 불릴 것이며'Inserted' 의사 테이블은 ** 여러 행 **을 포함 할 수 있습니다 ** -이 경우 - 여러 행 중 어느 것을 여기에서 선택 하시겠습니까 ??? SET ** ID = (SELECT I.ID_ FROM INSERTED I); .... 여러 행을 고려하여 적절하게 처리하려면 트리거를 다시 작성해야합니다 **! –

답변

2

트리거에서 PRINT를 사용하지 마십시오.

그리고 이런 식으로 정의 :

ALTER TRIGGER dbo.TriggerUpdateAdvert 
ON dbo.Advert FOR UPDATE 
AS 
    UPDATE Advert SET Published_Date=GETDATE() 
    WHERE ID_Advert IN (
    SELECT i.id 
    FROM inserted i 
    INNER JOIN deleted d 
    ON i.ID_Advert = d.ID_Advert 
    WHERE i.Status <> d.Status 
    AND i.Status IN (1,3) 
    ) 
END 
+0

감사! 네, 맞습니다. PRINT를 사용해서는 안됩니다. – POIR

1
UPDATE a SET Published_Date = CURRENT_TIMESTAMP 
    FROM dbo.Advert AS a 
    INNER JOIN inserted AS i ON a.ID_Advert = i.ID_Advert 
    INNER JOIN deleted AS d ON i.ID_Advert = d.ID_Advert 
    WHERE i.Status IN (1,3) AND d.Status <> i.Status; 
+0

감사! 귀하의 코드는 광산과 매우 유사합니다 (내 편집 부분 참조). – POIR

+0

@Otix 죄송합니다. 웬일인지 편집을 보지 못했습니다.이 질문에 앉아 생각 나지 않는 것 같습니다. 그래서 편집을 추가했습니다. , 아직 여기에 질문이 있습니까? 원래보고 한 오류 메시지가 생성 될 수는 없으므로 여기에서 찾고있는 다른 아이디어는 무엇입니까? –

+0

사실 나는 가장 빠른/최선의 방법을 찾고 있습니다 .... 이것이 유일한 방법이라면 괜찮습니다. 이 방법을 사용하겠습니다. – POIR

관련 문제