当表/数据库在Sql Server 2005上有插入/更新/删除时,有没有办法获取最新的日期时间?最好不要创建触发器..
我知道当你需要每行最后一次更新时,你需要触发器。但是,如果您只想获得整个表的最新更新,我不确定是否需要它们。
答案 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美分:
我考虑过使用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