2011-07-20 73 views
2

在此處使用Great Plains,我們的一位用戶不斷鎖定客戶數據,因此我們希望在客戶表上放置觸發器,以便我們找出它是誰。在SQL Server 2008 R2上創建觸發器以獲取記錄更新

無論如何,我創建了一個名爲audit_RM00101表如下:

DATE  nchar(10) 
CUSTNMBR char(15)  
CUSTNAME char(65)  
UPSZONE  char(3) 
SALSTERR char(15)  
USERID  nchar(100) 

我想捕捉從我希望審計,所以我寫的觸發如下表那些相同的字段:

CREATE TRIGGER CatchCustomerRegionUpdate 
ON RM00101 
FOR UPDATE 
AS 
DECLARE @UserID VARCHAR(128) 
SELECT @UserID = system_user 
INSERT INTO audit_RM00101 
SELECT DATE, CUSTNMBR, CUSTNAME, UPSZONE, SALSTERR, @UserID FROM UPDATED 

觸發器創建得很好,但當我試圖通過更新Great Plains中的客戶記錄來測試它時,Great Plains拋出了一個醜陋的錯誤,觸發器沒有被觸發。

我在這裏做錯了什麼?

謝謝。

在觸發
+0

你會得到什麼錯誤? – a1ex07

+0

你沒有告訴我們錯誤是什麼。 – Oded

+1

TSQL中沒有'UPDATED'僞表。這是實際的代碼,還是你嘲笑這個問題的類似東西? –

回答

5

,你得到的DELETEDINSERTED表,沒有UPDATED,所以用FROM INSERTED

同時更換FROM UPDATED嘗試解決您的USERID列,您audit_RM00101.USERIDnchar(100)@UserIDVARCHAR(128)

編輯基於OP評論:啊,所以沒有辦法審計何時通過使用觸發器更新表?

  • 在觸發刪除時,DELETED被填充,但INSERTED更新,DELETED填充了原來的值時,在觸發空
  • ,並INSERTED被填充了新的更新值
  • 在插入時觸發,DELETED爲空,但INSERTED有新的插入值
+0

感謝此功能。 – Tom

+0

我試着提出一個合適的選擇/妥協的'nchar(100)'vs'varchar(128)',但我從來沒有意識到如何記錄不足['SYSTEM_USER'](http://msdn.microsoft .com/en-us/library/ms179930.aspx)... –

+0

@Damien_The_Unbeliever,如果你把'system_user'的輸出放到sql_variant中,然後看SQL_VARIANT_PROPERTY'BaseType'和'MaxLength',你會發現它是一個nvarchar(128)。因此,audit_RM00101.USERID和@UserID都不正確。 –

3

SQL Server中沒有UPDATED;只是inserteddeleted。 此外,在爆發者身體的一開始添加IF @@ROWCOUNT = 0 RETURN是有意義的。 當UPDATE發生時,inserteddeleted表都不爲空。您可以添加以下代碼,以確保您處理UPDATE,不insert/delete

IF EXISTS(SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted) 
BEGIN 
-- handle update 
END ; 

,因爲你只是指定FOR UPDATE,如果你有,例如,FOR UPDATE, INSERT, DELETE這將是重要的它是不是你的觸發真的很重要。

+0

啊,所以沒有辦法通過使用觸發器來更新表時進行審計? – Tom

+1

'UPDATE'表示'inserted'和'deleted'不是空的。 – a1ex07

1

我們只有兩個魔錶稱爲inserted和deleted

更新間接是DELETE語句,然後插入語句。所以你必須更新INSERTED中存在的列的值。

CREATE TRIGGER CatchCustomerRegionUpdate 
ON RM00101 
AFTER UPDATE 
AS 
BEGIN 
    DECLARE @INSERTED INT, @DELETED INT 
    SET @INSERTED = SELECT COUNT(*) FROM INSERTED 
    SET @DELETED = SELECT COUNT(*) FROM DELETED 

    IF @INSERTED = 1 AND @DELETED = 1 
    BEGIN 
     UPDATE TABLE1 
     SET COL1 = INSERTED_COL1 
     WHERE IDCOL = INSERTED_IDCOL 

    END 

END