如何在Sql Server 2005上获取最后一次插入/更新/删除日期时间?

时间:2009-08-04 14:00:27

标签: sql-server sql-server-2005 tsql

不是my previous question

的副本

当表/数据库在Sql Server 2005上有插入/更新/删除时,有没有办法获取最新的日期时间?最好不要创建触发器..

我知道当你需要每行最后一次更新时,你需要触发器。但是,如果您只想获得整个表的最新更新,我不确定是否需要它们。

9 个答案:

答案 0 :(得分:14)

SELECT t.name,
       user_seeks,
       user_scans,
       user_lookups,
       user_updates,
       last_user_seek,
       last_user_scan,
       last_user_lookup,
       last_user_update
FROM   sys.dm_db_index_usage_stats i
       JOIN sys.tables t
         ON ( t.object_id = i.object_id )
WHERE  database_id = DB_ID() 

答案 1 :(得分:8)

您可以轻松获取上次插入/更新/删除的日期,如下所示:

CREATE FUNCTIOn fn_TablesLastUpdateDate(@Date NVARCHAR(20))

RETURNS @table TABLE(TableName NVARCHAR(40), LastUpdated Datetime)

AS

BEGIN


IF(@Date='') OR (@Date Is Null) OR (@Date='0')

    BEGIN
        INSERT INTO @table
        SELECT TOP 100 PERCENT TABLENAME,LASTUPDATED FROM 
        (
            SELECT  B.NAME AS 'TABLENAME', MAX(STATS_DATE (ID,INDID)) AS LASTUPDATED
            FROM    SYS.SYSINDEXES AS A
                    INNER JOIN SYS.OBJECTS AS B ON A.ID = B.OBJECT_ID
            WHERE   B.TYPE = 'U'  AND STATS_DATE (ID,INDID) IS NOT NULL 
            GROUP BY B.NAME
        ) AS A
        ORDER BY LASTUPDATED DESC
    END
ELSE

    BEGIN
        INSERT INTO @table
        SELECT TOP 100 PERCENT TABLENAME,LASTUPDATED FROM 
        (
            SELECT  B.NAME AS 'TABLENAME', MAX(STATS_DATE (ID,INDID)) AS LASTUPDATED,
                    CONVERT(VARCHAR, MAX(STATS_DATE (ID,INDID)), 103) as Date
            FROM    SYS.SYSINDEXES AS A
                    INNER JOIN SYS.OBJECTS AS B ON A.ID = B.OBJECT_ID
            WHERE   B.TYPE = 'U'  AND STATS_DATE (ID,INDID) IS NOT NULL 
            GROUP BY B.NAME
        ) AS A
        WHERE Date=@Date
        ORDER BY LASTUPDATED DESC
    END
RETURN

END



-- SELECT * from fn_TablesLastUpdateDate('06/11/2012')

答案 2 :(得分:6)

正如之前的两个答案所示,SQL Server中确实没有内置功能可以满足您的需求。

有大量动态管理视图可以告诉您一些您感兴趣的点,例如: sys.dm_db_index_usage_stats告诉您给定索引何时进行了最后一次搜索或更新。

但是你真的没有任何东西可以用来获取你正在寻找的所有信息 - 你真的必须自己做,加上例如将datetime字段添加到表中并用触发器填充它们。

对不起,我不能给你任何更好的消息 - 这就是现在的方式。

在SQL Server 2008中,您有其他新功能,可能会涵盖您的一些要求 - 请查看:

马克

答案 3 :(得分:3)

鉴于还没有答案,这是我的2美分:

  • 对于Insert,我会使用默认值为GETDATE()
  • 的DateTime字段
  • 对于Update,每次有更新时,我还会使用触发器修改的DateTime字段。
  • 对于删除,该记录将不可用,因此您无法进行查询。

我考虑过使用Timestamps来避免触发器,但是你无法将Timestamp转换为Datetime。

编辑: 或者也许您可以使用“metatable”,在触发器中您将保存更改日期

CREATE TABLE metatable (
table_name VARCHAR(40) NOT NULL PRIMARY KEY,
last_insert DATETIME NOT NULL,
last_update DATETIME NOT NULL,
last_delete DATETIME NOT NULL
)

INSERT metatable VALUES ('table1', GETDATE(), GETDATE(), GETDATE())

CREATE TRIGGER trg_table1_ins ON table1 FOR INSERT AS BEGIN
    UPDATE metatable SET last_insert = GETDATE() WHERE table_name = 'table1'
END

CREATE TRIGGER trg_table1_upd ON table1 FOR UPDATE AS BEGIN
    UPDATE metatable SET last_update = GETDATE() WHERE table_name = 'table1'
END

CREATE TRIGGER trg_table1_del ON table1 FOR DELETE AS BEGIN
    UPDATE metatable SET last_delete = GETDATE() WHERE table_name = 'table1'
END

我希望它有用

答案 4 :(得分:2)

在短期内(自服务器启动以来),您检查sys.dm_db_index_usage_stats last_user_update column。但是,由于这只会计算自服务器启动以来的更新,因此无法在很长一段时间内使用。

很长一段时间,如果表格不大,您的应用程序可以存储表格CHECKSUM_AGG(ALL)。在应用程序启动时,您只需要重新计算一次,并将其与先前存储的值进行比较。此外,应用程序可以使用DMV检测更改。在应用程序关闭时,它应该存储当前表校验和。

答案 5 :(得分:1)

没有触发器:您可以在表上有一个LastChgDate列,并在插入/更新/删除行时设置它。您必须通过将状态列设置为“D”或类似的东西来“删除”。在此列上放置索引并选择MAX()以查看何时进行更改。

答案 6 :(得分:1)

好吧,您可以保留一个“LastUpdateDate”列,该列设置为任何插入或更新时的当前服务器日期/时间。然后,您只需查询具有最新LastUpdateDate的行。

答案 7 :(得分:1)

我会将更改跟踪添加到组合中 - 与更改数据捕获相反,它不是仅限企业版功能。

http://msdn.microsoft.com/en-us/library/cc280462.aspx

了解相关信息

sys.dm_db_index_usage_stats类似,数据不会永远存在(虽然它可以在服务器重启后继续存在且可配置),您必须提取并保留您正在寻找的特定信息。

MDD

答案 8 :(得分:0)

简单!首先添加“LastUpdated”列。给它默认的GetDate()。这将处理插入语句。其次,添加一个更新触发器,将LastUpdated更新为GetDate()。现在涵盖了更新。最后添加一个位/布尔字段IsDeleted,默认值为0.如果用户想要删除一行,请翻转该位。因为当你“删除”一行时,实际上是在更新IsDeleted字段(因此正在使用Update操作),Deletes现在是带时间戳的。

要获取桌面上的最新活动: 只得到时间戳:

SELECT MAX(LastUpdated) FROM MyTable

获取更多信息:

SELECT MAX(LastUpdated), ID /*or whatever you need to know*/ FROM MyTable