2010-07-25 5 views
2

나는 다음과 같은 테이블이 있습니다업데이트 된 레코드를 기록 테이블로 이동하는 방법?

CREATE TABLE FE_USER 
(
    userid int identity (321,4) CONSTRAINT userid_pk PRIMARY KEY, 
    username varchar(40) 
); 

해당 기록 테이블은

CREATE TABLE FE_USER_HIST 
(
    userid int, 
    username varchar(40), 
    v_action varchar(50) 
); 

삽입 또는 업데이트가 FE_USER 테이블에 발생 때마다, 나는 입력 이 새로 삽입 된 기록 또는 필요하다 기록 테이블에 갱신 된 레코드.

어떻게 t-sql에서 트리거를 작성할 수 있습니까? 여기

내 pseducode입니다,하지만 난 오류가 많이 얻을 :

CREATE OR REPLACE TRIGGER user_to_hist 
    AFTER UPDATE OR DELETE 
    ON FE_USER 
    FOR EACH ROW 
    DECLARE 
     v_action varchar(50); 
    BEGIN 
     v_action := CASE WHEN UPDATING THEN 'UPDATE' ELSE 'DELETE' END; 
     INSERT INTO FE_USER_HIS(userid, username, v_action) 
     SELECT :OLD.userid, :OLD.username, v_action 
     FROM .......; 
END; 

답변

5

SQL 서버 불행히도 CREATE OR REPLACE를 지원하지 않습니다. 수행중인 작업에 따라 CREATE 또는 ALTER을 사용해야합니다.

또한 행 수준 트리거가 없습니다. 영향을받은 모든 행은 INSERTED 또는 DELETED

등의 의사 테이블에서 사용할 수 있습니다. 가장 간단한 방법은 아마도 2 개의 별도 트리거 일 수 있습니다.

CREATE TRIGGER dbo.tr_i_FE_USER 
    ON dbo.FE_USER 
    AFTER INSERT 
AS 
BEGIN 
    SET NOCOUNT ON; 
INSERT INTO FE_USER_HIST 
SELECT userid,username, 'inserted' AS v_action 
FROM INSERTED 

END 

그리고 업데이트

에 삽입

를 들어

CREATE TRIGGER dbo.tr_u_FE_USER 
    ON dbo.FE_USER 
    AFTER UPDATE 
AS 
BEGIN 
    SET NOCOUNT ON; 
INSERT INTO FE_USER_HIST 
SELECT userid,username, 'updated' AS v_action 
FROM INSERTED /*If you wanted the previous value instead 
       you could use FROM DELETED */ 

END 

그냥 내가 코멘트에서 언급 한 접근 방식에 후속

CREATE TRIGGER dbo.tr_iud_FE_USER 
    ON dbo.FE_USER 
    AFTER INSERT, UPDATE, DELETE 
AS 
BEGIN 
    SET NOCOUNT ON; 

    INSERT INTO FE_USER_HIST 
    SELECT 
    ISNULL(i.UserId,d.UserId) AS UserId, 

    CASE WHEN i.UserId IS NULL THEN d.UserName 
     ELSE i.UserName 
    END AS UserName, 

    CASE WHEN i.UserId IS NULL THEN 'deleted' 
     WHEN d.UserId IS NULL THEN 'inserted' 
     ELSE 'updated' 
    END AS v_action 
    from INSERTED i FULL OUTER JOIN DELETED d 
    ON i.UserId = d.USerId 
END 
+0

도 취한 조치를 결정하는 트리거 방법이있다 (그리고 쓸모없는 UPDATE() 함수의 사용에 대한 마틴의 올바른 코멘트 당 1 트리거로 통합하기) (즉, 삭제 또는 업데이트)? 나는 단 하나 방아쇠를 당기기 위하여 시도하고, 방법을 생각할 수 없었다. – LittleBobbyTables

+0

@LittleBobby - 당신은 행이 방금 삭제되었는지, 방금 삽입되었거나 또는 둘 다 (업데이트) –

+0

인지를 확인하기 위해 기본 키로 DELETED에 완전히 외부 조인을 삽입 할 수 있습니다 ... PK 자체가 업데이트되면 2 가지 방법으로 생성됩니다 다른 결과. –

2

모든 3 개 동작을 캡처하려면 I 1 개가 아닌 2 개의 트리거를 사용하십시오.

CREATE TRIGGER user_to_historyA ON FE_USER 
AFTER INSERT, UPDATE 
AS 
DECLARE @action varchar(50) 
    SET @action = CASE WHEN UPDATE(username) THEN 'UPDATE' ELSE 'INSERT' END 

    INSERT INTO FE_USER_HIS(userid, username, v_action) 
    SELECT userid, username, @action 
    FROM inserted 

GO 


CREATE TRIGGER user_to_historyB ON FE_USER 
AFTER DELETE 
AS 
    INSERT INTO FE_USER_HIS(userid, username, v_action) 
    SELECT userid, username, 'DELETE' 
    FROM deleted 

GO 

편집

ALTER TRIGGER user_to_history ON FE_USER 
    AFTER INSERT, UPDATE, DELETE 
    AS 
    DECLARE @action varchar(50) 
     IF EXISTS(SELECT username FROM inserted) 
     BEGIN 
      SET @action = CASE WHEN EXISTS(SELECT username FROM deleted) THEN 'UPDATE' ELSE 'INSERT' END 

      INSERT INTO FE_USER_HIS(userid, username, v_action) 
      SELECT userid, username, @action 
      FROM inserted 
     END 
     ELSE 
      INSERT INTO FE_USER_HIS(userid, username, v_action) 
      SELECT userid, username, 'DELETE' 
      FROM deleted 
    GO 
+0

좋은 생각이지만'INSERT '에 대해서도'UPDATE (username)'도 마찬가지라고 생각합니다. http://msdn.microsoft.com/en-us/library/ms187326.aspx. 'DELETED' 의사 테이블이 비 었는지 알 수 있습니다. (SQL2008의 병합을 위해서조차도 Insert와 Update 트리거는 별도의 액션으로 실행되기 때문에 SQL2008에서도 작동합니다.) –

+0

고마워 .......... –

관련 문제