How do I add a “last modified” and “created” column in a SQL Server table?

前端 未结 5 1091
误落风尘
误落风尘 2020-12-13 01:57

I\'m design a new db schema for a SQL Server 2012 database.

Each table should get two extra columns called modified and created which shoul

5条回答
  •  不思量自难忘°
    2020-12-13 02:44

    One important thing to consider is that you should always have the inserted / updated time for all of your tables and rows be from the same time source. There is a danger - if you do not use triggers - that different applications making direct updates to your tables will be on machines that have different times on their clocks, or that there will not be consistent use of local vs. UTC in the application layer.

    Consider a case where the system making the insert or update query that directly sets the updated / modified time value has a clock that is 5 minutes behind (unlikely, but worth considering) or is using local time versus UTC. If another system is polling using an interval of 1 minute, it might miss the update.

    For a number of reasons, I never expose my tables directly to applications. To handle this situation, I create a view on the table explicitly listing the fields to be accessed (including the updated / modified time field). I then use an INSTEAD OF UPDATE, INSERT trigger on the view and explicitly set the updatedAt time using the database server's clock. This way I can guarantee that the timebase for all records in the database is identical.

    This has a few benefits:

    1. It only makes one insert to the base table and you don't have to worry about cascading triggers being called
    2. It allows me to control at the field level what information I expose to the business layer or to other consumers of my data
    3. It allows me to secure the view independently from the base table

    It works great on SQL Azure.

    Take a look at this example of the trigger on the view:

    ALTER TRIGGER [MR3W].[tgUpdateBuilding] ON [MR3W].[vwMrWebBuilding]
    INSTEAD OF UPDATE, INSERT AS
    BEGIN
    
    SET NOCOUNT ON
    
    IF EXISTS(SELECT * FROM DELETED)
    BEGIN
        UPDATE [dbo].[Building]
           SET 
              ,[BuildingName] = i.BuildingName
              ,[isActive] = i.isActive
              ,[updatedAt] = getdate()
         FROM dbo.Building b
         inner join inserted i on i.BuildingId = b.BuildingId
    END
    ELSE
    BEGIN
    INSERT INTO [dbo].[Building]
               (
                [BuildingName]
               ,[isActive]
               ,[updatedAt]
               )
    
               SELECT 
                   [BuildingName]
                  ,[isActive]
                  ,getdate()
                  FROM INSERTED
        END
    END
    

    I hope this helps, and I would welcome comments if there are reasons this is not the best solution.

提交回复
热议问题