触发创建/修改以确保字段等于插入日期

时间:2018-06-15 12:15:46

标签: sql sql-server tsql datetime triggers

我有一个名为Customer的表格,有问题的列是dbupddate。此列应包含导致记录bein插入的查询的日期时间。

我已经为getdate()制定了默认约束:

CREATE TABLE [dbo].[customer]
(
    [dbupddate] [DATETIME] NOT NULL 
         CONSTRAINT [DF_customer_dbupddate] DEFAULT (GETDATE()),...

但这并不能阻止某人偶然输入无关的值。

如何确保列dbupddate具有插入日期时间?

我猜答案会包含一个触发器。在这种情况下,请考虑以下已存在的触发器,它不应以任何方式丢失/修改其效果:

CREATE TRIGGER [dbo].[customer_ins_trig]
ON [dbo].[customer]
AFTER INSERT
AS 
BEGIN
    DELETE u
    FROM transfer_customer_unprocessed u
    WHERE EXISTS (SELECT 1 FROM inserted i WHERE i.code = u.code)

    INSERT INTO transfer_customer_unprocessed (code, dbupddate)
        SELECT code, dbupddate
        FROM inserted
END

也许我可以添加一些线来满足我的需求?或者可能创建另一个?

2 个答案:

答案 0 :(得分:0)

在插入数据的过程中,不要为该列提供变量。如果他们拥有权利并对其进行更新,则有人可以打开SSMS,但您也可以通过访问来限制它。

此外,如果这是跟踪更改的更大计划的一部分,您可能需要查看rowversion

答案 1 :(得分:0)

我认为这是一个可以满足您需求的触发器。请注意,用户无法控制进入InsertDate的内容。

这是保持数据“最新更新”信息的合理方法。但是,@ scsimon如果你出于其他原因这样做,ROWVERSION值得探索,不需要触发器,并且性能会更高。

DROP TABLE IF EXISTS Test;
GO

CREATE TABLE Test (
    Id INT NOT NULL ,
    Content NVARCHAR(MAX) NOT NULL ,
    InsertDate DATETIME NULL
);
GO

CREATE TRIGGER TR_Test
ON Test
AFTER INSERT, UPDATE
AS BEGIN
    UPDATE t SET t.InsertDate = GETDATE() FROM Test t INNER JOIN inserted i ON i.Id = t.Id;
END;
GO

INSERT Test VALUES (1, '1', NULL), (2, '2', NULL), (3, '3', NULL);
SELECT * FROM Test;
GO

UPDATE Test SET Id = 4, Content = 4 WHERE Id = 1;
UPDATE Test SET Id = 5, Content = 5, InsertDate = NULL WHERE Id = 2;
SELECT * FROM Test;
GO