2017-05-09 24 views
2

我有一個表創建日期和創建用戶字段定義,似乎工作。如何將行更新時間和行更新用戶添加到表中?

但我很難創建一個功能正常的行更新日期時間和行更新字段。

我想如何工作:當有人更新表中的記錄時,日期/時間和用戶名被記錄爲只有記錄被更新。

這裏是我的失敗創建觸發器語法,我已經不正確改編自上看到堆棧溢出的答案:

我要指出,我不明白的地方的「插入」表在其他許多前來例子。也不是爲什麼它和內部連接起作用。

CREATE TRIGGER mkt.Update_tbl_fTesting 
    ON mkt.tbl_fTesting 
    FOR UPDATE 
AS 

BEGIN 
    SET NOCOUNT ON; 

    UPDATE mkt.tbl_fTesting 
    SET RowUpdateDateTime = GetDate() 
     , RowUpdateBy = coalesce(SUSER_SNAME(), '?') 
    FROM mkt.tbl_fTesting 
    INNER JOIN inserted 
    ON tbl_fTesting.tbl_fTestingIdentity = inserted.ID; 
END 
GO 

上執行的觸發創作語法錯誤是:

無效列名稱 'ID'

這裏是我的預期表的創建語法工作:

USE [ObscuredDatabase] 
GO 

DROP TABLE [mkt].[tbl_fTesting] 
GO 

SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

CREATE TABLE [mkt].[tbl_fTesting](
    [tbl_TestingIdentity] [bigint] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL, 
    [Produce] [nvarchar] (25) NOT NULL, 
    [Color] [nvarchar] (25) NOT NULL, 
    [RowCreateDateTime] [datetime] NULL DEFAULT (getdate()), 
    [RowCreateBy] [nvarchar](max) NULL DEFAULT (coalesce(suser_sname(),'?')), 
    [RowUpdateDateTime] [datetime] NULL, 
    [RowUpdateBy] [nvarchar](max) NULL 
PRIMARY KEY CLUSTERED 
(
    [tbl_fTestingIdentity] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [SECONDARY] 
) ON [SECONDARY] 

GO 

回答

2

我要指出,我不明白的地方的「插入」表在其他許多例子來 。也不是爲什麼它和內部連接起作用。

你真的很接近。將inserted表視爲臨時表,其中包含將被插入或更新的記錄。它與接收更新的表具有相同的結構。

因此,所有你需要做的是在你的JOIN使用正確的列名從inserted表,這將匹配mkt.tbl_fTesting列名:

CREATE TRIGGER mkt.Update_tbl_fTesting 
    ON mkt.tbl_fTesting 
    FOR UPDATE 
AS 

BEGIN 
    SET NOCOUNT ON; 

    UPDATE FTest 
    SET RowUpdateDateTime = GetDate() 
     , RowUpdateBy = coalesce(SUSER_SNAME(), '?') 
    FROM mkt.tbl_fTesting FTest 
    INNER JOIN inserted 
    ON FTest.tbl_fTestingIdentity = inserted.tbl_fTestingIdentity; 
END 
GO 

編輯更多信息:

想象一下,一個簡單的表格,Clothes

ID | Type | Color | RowUpdateDateTime 
1 | Sock | Pink | NULL 
2 | Sock | Red | NULL 
3 | Shirt | Blue | NULL 

你運行一個簡單的更新:

UPDATE Clothes 
SET Color = 'Green' 
WHERE Type = 'Sock' 

在執行時,一個inserted表將被創建,並且將包含新行:

ID | Type | Color | RowUpdateDateTime 
1 | Sock | Green | NULL 
2 | Sock | Green | NULL 

,您的觸發會那麼火斷更新到RowUpdateDateTime柱:

UPDATE C 
SET RowUpdateDateTime = GETDATE() 
FROM Clothes C 
INNER JOIN inserted i ON i.ID = C.ID; 

哪個連接謂詞i.ID = C.ID的,因爲會只更改修正後的d吃了受原始更新行

決賽Clothes表:

ID | Type | Color | RowUpdateDateTime 
1 | Sock | Green | 2017-05-09 16:32:09.873 
2 | Sock | Green | 2017-05-09 16:32:09.873 
3 | Shirt | Blue | NULL 
+0

那麼這是否意味着插入的表在本次更新時基本上會有一行? – ChrisG

+1

@ChrisG不太......它將有相同數量的原始更新正在更新的行數。這就是爲什麼你必須在條件下真正加入它。將X個原始行鏈接到X個插入行。希望這是有道理的。 –

+1

它有一點意義,但我只需要做一些獨立的閱讀和研究。謝謝! – ChrisG

8

那麼,你的表的主鍵不叫ID,被稱爲tbl_TestingIdentity,所以在插入時你需要使用這個列名。 (inserted.tbl_TestingIdentity)

+1

謝謝Rigerta,你的答案是絕對正確的,對我 – ChrisG

+1

編碼愉快的工作! :) –

相關問題