SQL - 仅当用户进行更新时触发插入
SQL - trigger insert only when a user made an update
我有一个 table、customers_accounts
,用于跟踪帐户中客户的一些基本信息。当客户的文件被打开时,我从外部系统同步信息,以便我们的用户获得最新的信息。
UPDATE
customers_accounts
SET
first_name = 'bob',
last_name = 'burger'
WHERE
account_number = '12345'
当用户更新帐户时,我执行相同的查询,但我更新了一个列,指示最后一个进行更改的用户
UPDATE
customers_accounts
SET
first_name = 'bob',
last_name = 'burger',
updated_by = 'H Jon Benjamin',
updated_on = GETDATE()
WHERE
account_number = '12345'
这是我要解决的问题。我想跟踪历史记录 table 中的更改,但只记录用户所做的更改,而不是来自外部系统的更改。所以我的计划是创建一个触发器,如果用户列在插入时不为空,则插入一行(因为 updated_by
在上面的第一次更新中隐式为空)
我试过的是这样的:
ALTER trigger [dbo].[Accounts_Customers_LogUpdate]
ON [dbo].[Accounts_Customers]
AFTER UPDATE
AS
DECLARE @Now AS DATETIME = GETDATE()
DECLARE @User AS NVARCHAR(150)
SELECT @User = (SELECT [updated_by] FROM INSERTED)
IF (@User IS NOT NULL)
BEGIN
SET NOCOUNT ON
INSERT INTO [dbo].[Accounts_Customers-History]
SELECT *, @User, @Now
FROM inserted
END
Accounts_Customers-History
是 table 的精确副本,带有两个额外的列,change_made_by
和 change_made_on
它的表现与我预期的不同。它会将 updated_by
中的任何值插入到 change_made_by
中,而不管查询中 updated_by
的值如何。所以我正在记录 activity 由用户和导入触发。
为此使用 UPDATE()
:
Returns a Boolean value that indicates whether an INSERT or UPDATE attempt was made on a specified column of a table or view. UPDATE() is used anywhere inside the body of a Transact-SQL INSERT or UPDATE trigger to test whether the trigger should execute certain actions.
这意味着 update
函数将 return false
用于问题中的第一个更新语句,而 true
用于第二个更新语句 - 这正是你需要什么。
另外,请注意您应该始终在插入语句中指定列列表,
并且始终在 select 语句中指定列列表。 ()
您的触发器的修订版本可能如下所示:
ALTER TRIGGER [dbo].[Accounts_Customers_LogUpdate]
ON [dbo].[Accounts_Customers]
AFTER UPDATE
AS
DECLARE @Now as DateTime = GetDate()
IF UPDATE(updated_by)
BEGIN
-- Always specify the columns list in an insert statement!
insert into [dbo].[Accounts_Customers-History] (<Columns list>)
-- Always specify the columns list in a select statement!
select <columns list>, @Now
from inserted
END
请注意,如果触发触发器的插入或更新语句成功,UPDATE()
函数不会向您提供任何指示,也不会向您提供列值是否实际更改的指示- 它仅指示该列是否是触发触发器的插入或更新语句的一部分 - 正如您在备注部分的最后一段中所读:
If a trigger applies to a column, the UPDATED value will return as true or 1, even if the column value remains unchanged. This is by-design, and the trigger should implement business logic that determines if the insert/update/delete operation is permissible or not.
我有一个 table、customers_accounts
,用于跟踪帐户中客户的一些基本信息。当客户的文件被打开时,我从外部系统同步信息,以便我们的用户获得最新的信息。
UPDATE
customers_accounts
SET
first_name = 'bob',
last_name = 'burger'
WHERE
account_number = '12345'
当用户更新帐户时,我执行相同的查询,但我更新了一个列,指示最后一个进行更改的用户
UPDATE
customers_accounts
SET
first_name = 'bob',
last_name = 'burger',
updated_by = 'H Jon Benjamin',
updated_on = GETDATE()
WHERE
account_number = '12345'
这是我要解决的问题。我想跟踪历史记录 table 中的更改,但只记录用户所做的更改,而不是来自外部系统的更改。所以我的计划是创建一个触发器,如果用户列在插入时不为空,则插入一行(因为 updated_by
在上面的第一次更新中隐式为空)
我试过的是这样的:
ALTER trigger [dbo].[Accounts_Customers_LogUpdate]
ON [dbo].[Accounts_Customers]
AFTER UPDATE
AS
DECLARE @Now AS DATETIME = GETDATE()
DECLARE @User AS NVARCHAR(150)
SELECT @User = (SELECT [updated_by] FROM INSERTED)
IF (@User IS NOT NULL)
BEGIN
SET NOCOUNT ON
INSERT INTO [dbo].[Accounts_Customers-History]
SELECT *, @User, @Now
FROM inserted
END
Accounts_Customers-History
是 table 的精确副本,带有两个额外的列,change_made_by
和 change_made_on
它的表现与我预期的不同。它会将 updated_by
中的任何值插入到 change_made_by
中,而不管查询中 updated_by
的值如何。所以我正在记录 activity 由用户和导入触发。
为此使用 UPDATE()
:
Returns a Boolean value that indicates whether an INSERT or UPDATE attempt was made on a specified column of a table or view. UPDATE() is used anywhere inside the body of a Transact-SQL INSERT or UPDATE trigger to test whether the trigger should execute certain actions.
这意味着 update
函数将 return false
用于问题中的第一个更新语句,而 true
用于第二个更新语句 - 这正是你需要什么。
另外,请注意您应该始终在插入语句中指定列列表,
并且始终在 select 语句中指定列列表。 (
您的触发器的修订版本可能如下所示:
ALTER TRIGGER [dbo].[Accounts_Customers_LogUpdate]
ON [dbo].[Accounts_Customers]
AFTER UPDATE
AS
DECLARE @Now as DateTime = GetDate()
IF UPDATE(updated_by)
BEGIN
-- Always specify the columns list in an insert statement!
insert into [dbo].[Accounts_Customers-History] (<Columns list>)
-- Always specify the columns list in a select statement!
select <columns list>, @Now
from inserted
END
请注意,如果触发触发器的插入或更新语句成功,UPDATE()
函数不会向您提供任何指示,也不会向您提供列值是否实际更改的指示- 它仅指示该列是否是触发触发器的插入或更新语句的一部分 - 正如您在备注部分的最后一段中所读:
If a trigger applies to a column, the UPDATED value will return as true or 1, even if the column value remains unchanged. This is by-design, and the trigger should implement business logic that determines if the insert/update/delete operation is permissible or not.