基本上我想将所有已更新的行复制到另一个SQL历史记录表中,但要附加“版本”列
CREATE TRIGGER [dbo].TriggerName
ON [dbo].[Users]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [dbo].[UsersHistory] ([AspNetUserId], [CreditCustomerId],
[UserName], [GivenNames], [Surname],
[Email], [PhoneNumber], [Active],
[Administrator], [AutomaticSuspension],
[CurrentVersion], [Version], [Notes],
[LastUpdateId], [LastUpdateDate])
SELECT
Id, CreditCustomerId,
UserName, GivenNames, Surname,
Email, PhoneNumber, Active,
Administrator, AutomaticSuspension,
1,
(SELECT ISNULL(MAX(VERSION) + 1, 1)
FROM [dbo].AspNetUsersHistory
WHERE AspNetUserId = (SELECT Id from DELETED)),
Notes,
0, GETDATE()
FROM
DELETED
END
如果这样做,我会在下面出现错误
子查询返回了多个值。当子查询遵循=,!=,<,<=,>,> =
时,不允许这样做
基本上,我想为每个用户更新版本列,因此每当用户更改详细信息时,它应该为1,2或3。
答案 0 :(得分:1)
更改
(SELECT ISNULL(MAX(VERSION) + 1, 1) from [dbo].AspNetUsersHistory
WHERE AspNetUserId = (SELECT Id from DELETED)),
到
(SELECT ISNULL(MAX(VERSION) + 1, 1) from [dbo].AspNetUsersHistory
WHERE AspNetUserId = deleted.ID),
不需要(从已删除的ID中选择)-这是一个子查询,它可以直接看到正在处理的父行。
编辑后添加
要更新记录的所有先前版本以将CurrentVersion设置为false,请将其置于插入上方的触发器内-它应首先运行
UPDATE UH SET CurrentVersion = 0
FROM dbo.[UsersHistory] UH
INNER JOIN deleted D on D.Id = UH.[AspNetUserId]
WHERE UH.CurrentVersion <> 0;
答案 1 :(得分:0)
您需要记住,特殊表Deleted将不仅包含一行,而且包含触发更新语句一部分的完整行集。因此,如果您在一条语句中更新10行,则DELETED表中将包含10行。这是您的WHERE AspNetUserId = (SELECT Id from DELETED))
失败的地方。我倾向于将它们全部带有时间戳记写在历史记录表中,如果以后需要转换为版本号,请稍后使用查询。用这种方式完成的版本号总是有问题的。
答案 2 :(得分:0)
您不应在派生表中再有一条SELECT语句。只需使用SELECT语句中的ID,如下所示:
INSERT INTO [dbo].[UsersHistory] ([AspNetUserId], [CreditCustomerId],
[UserName], [GivenNames], [Surname],
[Email], [PhoneNumber], [Active],
[Administrator], [AutomaticSuspension],
[CurrentVersion], [Version], [Notes],
[LastUpdateId], [LastUpdateDate])
SELECT
Id, CreditCustomerId,
UserName, GivenNames, Surname,
Email, PhoneNumber, Active,
Administrator, AutomaticSuspension,
1,
(SELECT ISNULL(MAX(VERSION) + 1, 1)
FROM [dbo].AspNetUsersHistory
WHERE AspNetUserId = d.Id),
Notes,
0, GETDATE()
FROM
DELETED as d;