2017-05-09 27 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

编码愉快的工作! :) –

相关问题