【发布时间】:2019-02-25 00:30:17
【问题描述】:
我想知道UserId 何时更改为当前值。
假设我们有一张桌子Foo:
Foo
Id | UserId
---+-------
1 | 1
2 | 2
现在我需要能够执行如下查询:
SELECT UserId, UserIdModifiedAt FROM Foo
幸运的是,我已将历史记录中的所有更改记录到表 FooHistory:
FooHistory
Id | FooId | UserId | FooModifiedAt
---|-------+--------+---------------
1 | 1 | NULL | 1.1.2019 02:00
2 | 1 | 2 | 1.1.2019 02:01
3 | 1 | 1 | 1.1.2019 02:02
4 | 1 | 1 | 1.1.2019 02:03
5 | 2 | 1 | 1.1.2019 02:04
6 | 2 | 2 | 1.1.2019 02:05
7 | 2 | 2 | 1.1.2019 02:06
所以我们需要的所有数据都是可用的(Foo #1 的用户最后修改时间是 02:02,Foo #2 的用户是 02:05)。我们将在Foo 中添加一个新列UserIdModifiedAt
Foo v2
Id | UserId | UserIdModifiedAt
---+--------|-----------------
1 | 1 | NULL
2 | 2 | NULL
... 并使用触发器设置其值。美好的。但是如何迁移历史呢?什么脚本会为我们填写UserIdModifiedAt?
查看表结构示例:
DROP TABLE IF EXISTS [Foo]
DROP TABLE IF EXISTS [FooHistory]
CREATE TABLE [Foo]
(
[Id] INT NOT NULL CONSTRAINT [PK_Foo] PRIMARY KEY,
[UserId] INT,
[UserIdModifiedAt] DATETIME2 -- Automatically updated based on a trigger
)
CREATE TABLE [FooHistory]
(
[Id] INT IDENTITY NOT NULL CONSTRAINT [PK_FooHistory] PRIMARY KEY,
[FooId] INT,
[UserId] INT,
[FooModifiedAt] DATETIME2 NOT NULL CONSTRAINT [DF_FooHistory_FooModifiedAt] DEFAULT (sysutcdatetime())
)
GO
CREATE TRIGGER [trgFoo]
ON [dbo].[Foo]
AFTER INSERT, UPDATE
AS
BEGIN
IF EXISTS (SELECT [UserId] FROM inserted EXCEPT SELECT [UserId] FROM deleted)
BEGIN
UPDATE [Foo] SET [UserIdModifiedAt] = SYSUTCDATETIME() FROM [inserted] WHERE [Foo].[Id] = [inserted].[Id]
END
INSERT INTO [FooHistory] ([FooId], [UserId])
SELECT [Id], [UserId] FROM inserted
END
GO
/* Test data */
INSERT INTO [Foo] ([Id], [UserId]) VALUES (1, NULL)
WAITFOR DELAY '00:00:00.010'
UPDATE [Foo] SET [UserId] = NULL
WAITFOR DELAY '00:00:00.010'
UPDATE [Foo] SET [UserId] = 1
WAITFOR DELAY '00:00:00.010'
UPDATE [Foo] SET [UserId] = 1
WAITFOR DELAY '00:00:00.010'
SELECT * FROM [Foo]
SELECT * FROM [FooHistory]
【问题讨论】:
-
为什么不使用临时表?
-
@ArnaudPeralta 澄清了这个问题。我们需要快速执行查询 SELECT UserId, UserIdModifiedAt FROM Foo。请注意,UserIdModifiedAt 具体与 UserId 值相关。我认为临时表在这里对我们没有帮助;在跟踪行何时被修改时,它不会向我们提供有关特定值上次修改时间的信息?
标签: sql-server tsql