【发布时间】:2018-04-21 01:48:41
【问题描述】:
我想将表 Item 中的任何字段更改记录到名为 Events 的日志表中。
CREATE TABLE [dbo].[Items]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](100) NULL,
[Description] [nvarchar](max) NULL,
[ParentId] [int] NULL,
[EntityStatusId] [int] NOT NULL,
[ItemTypeId] [int] NOT NULL,
[StartDate] [datetimeoffset](7) NULL,
[DueDate] [datetimeoffset](7) NULL,
[Budget] [decimal](18, 2) NULL,
[Cost] [decimal](18, 2) NULL,
[Progress] [int] NULL,
[StatusTypeId] [int] NULL,
[ImportanceTypeId] [int] NULL,
[PriorityTypeId] [int] NULL,
[CreatedDate] [datetimeoffset](7) NULL,
[HideChildren] [bit] NOT NULL,
[TenantId] [int] NOT NULL,
[OwnedBy] [int] NOT NULL,
[Details] [nvarchar](max) NULL,
[Inserted] [datetimeoffset](0) NOT NULL,
[Updated] [datetimeoffset](0) NOT NULL,
[InsertedBy] [int] NULL,
[UpdatedBy] [int] NULL,
)
对于每个更改的列,我想在此表中添加一行。此表将保存 Item 表的更改,但稍后它将保存其他表的更改。我希望触发器尽可能动态,因此相同的基本触发器也可以用于其他表。如果向表中添加/删除列,SP 应该发现这一点并且不会中断。
CREATE TABLE [dbo].[Events]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[RecordId] [int] NOT NULL, -- Item.Id
[EventTypeId] [int] NOT NULL, -- Always 2
[EventDate] [datetimeoffset](0) NOT NULL, --GetUTCDate()
[ColumnName] [nvarchar](50) NULL, --The column name that changed
[OriginalValue] [nvarchar](max) NULL, --The original Value
[NewValue] [nvarchar](max) NULL, --The New Value
[TenantId] [int] NOT NULL, --Item.TentantId
[AppUserId] [int] NOT NULL, --Item.ModifiedBy
[TableName] [int] NOT NULL --The Name of the Table (Item in this case, but later there will be others)
)
我正在尝试编写更新触发器,但发现它很困难。
我知道有保存新旧值的 Inserted 和 Deleted 表。
那么我该如何实现呢?它似乎应该是动态的,这样如果添加列,它就不会破坏任何东西。
如果我在 C# 中编写此代码,我将获取所有列名并遍历它们并找到更改的字段,然后为每个字段创建一个事件。但我不知道如何使用 SQL 来做到这一点。
响应答案的更新:
在 SSMS 中编辑时,此答案有效。然而,在实践中,该应用程序使用 EntityFramework 并且它似乎在做一些奇怪的事情,因为这是被记录的内容。请注意,在 Original/New 中实际上只有一列具有不同的值。因此,我试图在插入之前检查这些值是否真的不同。
+----+----------+-------------+----------------------------+------------------+----------------------------+----------------------------+----------+-----------+---------+-----------+
| Id | RecordId | EventTypeId | EventDate | ColumnName | OriginalValue | NewValue | TenantId | AppUserId | TableId | TableName |
+----+----------+-------------+----------------------------+------------------+----------------------------+----------------------------+----------+-----------+---------+-----------+
| 21 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | Name | Task 2 | Task 2A | 8 | 11 | NULL | Item |
| 22 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | Description | NULL | NULL | 8 | 11 | NULL | Item |
| 23 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | ParentId | 238 | 238 | 8 | 11 | NULL | Item |
| 24 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | EntityStatusId | 1 | 1 | 8 | 11 | NULL | Item |
| 25 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | ItemTypeId | 3 | 3 | 8 | 11 | NULL | Item |
| 26 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | StartDate | NULL | NULL | 8 | 11 | NULL | Item |
| 27 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | DueDate | NULL | NULL | 8 | 11 | NULL | Item |
| 28 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | Budget | NULL | NULL | 8 | 11 | NULL | Item |
| 29 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | Cost | NULL | NULL | 8 | 11 | NULL | Item |
| 30 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | Progress | NULL | NULL | 8 | 11 | NULL | Item |
| 31 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | StatusTypeId | 1 | 1 | 8 | 11 | NULL | Item |
| 32 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | ImportanceTypeId | NULL | NULL | 8 | 11 | NULL | Item |
| 33 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | PriorityTypeId | NULL | NULL | 8 | 11 | NULL | Item |
| 34 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | OwnedBy | 11 | 11 | 8 | 11 | NULL | Item |
| 35 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | Details | <p><span></span></p> | <p><span></span></p> | 8 | 11 | NULL | Item |
| 36 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | Inserted | 0001-01-01 00:00:00 +00:00 | 0001-01-01 00:00:00 +00:00 | 8 | 11 | NULL | Item |
| 37 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | Updated | 0001-01-01 00:00:00 +00:00 | 0001-01-01 00:00:00 +00:00 | 8 | 11 | NULL | Item |
| 38 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | InsertedBy | 11 | 11 | 8 | 11 | NULL | Item |
| 39 | 397 | 2 | 2018-04-22 15:42:16 +00:00 | UpdatedBy | 11 | 11 | 8 | 11 | NULL | Item |
+----+----------+-------------+----------------------------+------------------+----------------------------+----------------------------+----------+-----------+---------+-----------+
【问题讨论】:
-
阅读那个,它是关于创建 XML 的。
-
您应该在
Events表中添加一些解释。什么是RecordId, EventTypeId列?它们不在Items表中。如果您只从一个表中记录,那么TableId列的目的是什么。而如果几列同时更新,你会插入几行吗? -
因此,您想为每个更新的行和每个更新的列在
dbo.Events表中添加一个新行?我将此假设基于其中包含ColumnName属性。如果这是正确的假设,那么您正在寻找的是编写即使您更改dbo.Items架构也能正常工作的代码?只是想弄清楚你到底在找什么,甚至可以在你上面的问题中添加我的问题的答案,这样当有人读到它时,它会立即阐明你的意图。 -
@MK_ 好点,我已经编辑了我上面的问题以澄清。
标签: sql-server sql-server-2012