如何在SQL Server表中添加“上次修改”和“已创建”列?

问题描述 投票:28回答:3

我正在为SQL Server 2012数据库设计一个新的数据库模式。

每个表都应该有两个名为modifiedcreated的额外列,这些列应该在插入或更新行时自动更改。

我不知道怎样才能到达那里。

我认为触发器是处理它的最佳方式。

我试图找到触发器的例子..但是我发现在另一个表中插入数据的教程等。

我认为这是一个很常见的场景,但我还没有找到答案。

sql-server tsql triggers sql-server-2012
3个回答
41
投票

created列很简单 - 只是一个DATETIME2(3)列,默认约束在插入新行时设置:

Created DATETIME2(3) 
   CONSTRAINT DF_YourTable_Created DEFAULT (SYSDATETIME())

因此,当您在YourTable中插入一行并且没有为Created指定值时,它将被设置为当前日期和时间。

modified有点工作,因为你需要为AFTER UPDATE案例编写一个触发器并更新它 - 你不能声明地告诉SQL Server为你做这个....

Modified DATETIME2(3)

然后

CREATE TRIGGER updateModified
ON dbo.YourTable
AFTER UPDATE 
AS
   UPDATE dbo.YourTable
   SET modified = SYSDATETIME()
   FROM Inserted i
   WHERE dbo.YourTable.PrimaryKey = i.PrimaryKey

您需要加入Inserted伪表,其中包含使用您的主表上的基表更新的所有行。

而且你必须为你希望拥有AFTER UPDATE列的每个表创建这个modified触发器。


8
投票

通常,您可以拥有以下列:

  • LastModifiedBy
  • LastModifiedOn
  • 由...制作
  • 创建于

其中LastModifiedByCreatedBy是对users表(UserID)的引用,而LastModifiedOnCreatetOn列是日期和时间列。

您有以下选择:

  1. 没有触发器的解决方案 - 我已经在某处读过“编写触发器的最佳方法是不写这样的。”而你应该知道,他们通常会伤害到表现。所以,如果你可以避免它们,最好这样做,即使使用触发器在某些情况下看起来最简单。 因此,只需编辑所有INSERTUPDATE语句,以包含当前的UserID和当前日期和时间。如果无法定义此类user ID(匿名用户),则可以使用0而不是列的默认值(如果未指定user ID,则为NULL)。当您看到插入NULL值时,您应该找到“有罪”语句并进行编辑。
  2. 带触发器的解决方案 - 您可以创建AFTER INSERT, UPDATE触发器并在那里填充用户列。在触发器的上下文中很容易获得当前日期和时间(例如,使用GETUTCDATE())。这里的问题是触发器不允许传递/接受参数。因此,因为您没有插入user ID值而您无法将其传递给触发器。如何找到当前用户? 你可以使用SET CONTEXT_INFOCONTEXT_INFO。在你所有insertupdate陈述之前,你必须使用SET CONTEXT_INFOcurrent user ID添加到当前上下文,并在触发器中使用CONTEXT_INFO函数来提取它。

因此,当使用触发器时,您再次需要编辑所有INSERTUPDATE子句 - 这就是为什么我不想使用它们。

无论如何,如果您只需要具有日期和时间列而不是按列创建/修改,则使用触发器会更耐用,更容易,因为您现在和将来都不会编辑任何其他语句。


使用SQL Server 2016,我们现在可以使用SESSION_CONTEXT函数来读取会话详细信息。细节使用sp_set_session_context(如read-onlyread and write)设置。这些东西有点用户友好:

EXEC sp_set_session_context 'user_id', 4;  
SELECT SESSION_CONTEXT(N'user_id');  

一个不错的example


1
投票

注意,上面工作正常,但并非在所有情况下,我失去了很多时间,发现这有用:

create TRIGGER yourtable_update_insert
ON yourtable
AFTER UPDATE 
as
begin
   set nocount on;
   update yourtable set modified=getdate(), modifiedby = suser_sname()
   from  yourtable t 
   inner join inserted i on t.uniqueid=i.uniqueid 
end
go

你需要set nocount on;,否则你会得到错误:


Microsoft SQL Server Management Studio


没有更新行。

第5行中的数据未提交。错误源:Microsoft.SqlServer.Management.DataTools。错误消息:更新或删除的行值不会使行唯一,也不会更改多行(2行)。

更正错误并重试,或按ESC取消更改。


好的帮助


© www.soinside.com 2019 - 2024. All rights reserved.