SQL Server行日期最后修改

时间:2011-06-14 13:40:05

标签: sql sql-server

我的一位同事说SQL Server将上次修改的日期和时间保存在每个记录的“隐藏列”中。我很确定他说错了。你能向我证实一下吗?

6 个答案:

答案 0 :(得分:42)

没有基于每行维护的隐藏列,其中包含上次修改的日期/时间。也没有包含执行此类更改的用户身份的列,也没有列标识最后执行的更改(插入或更新)。

如果您想要任何这些功能,则必须实施它们。对于某些用户来说,每一个开销都可能对他们很重要,因此隐藏功能(隐藏成本)是不可接受的。

答案 1 :(得分:41)

正如其他人所暗示的那样,你的同事一定是在说胡言乱语,或者指的是别的东西。为此目的,记录或页面的磁盘上结构不包含对上次更新时间的任何引用。虽然您可以在对象级别找到有关上次更新的信息,但在记录/行级别上没有此类信息。

答案 2 :(得分:11)

Pinal Dave开始,您可以使用DMV获取此信息。您的同事可能会在TIMESTAMP中提及已修改的行,但据我所知,只有通过明确添加该类型的列才能保证这一点。

SELECT OBJECT_NAME(OBJECT_ID) AS DatabaseName, last_user_update,*
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID( 'AdventureWorks')
AND OBJECT_ID=OBJECT_ID('test');

答案 3 :(得分:7)

如果您想知道上次更新特定行的时间,您应该在表中维护一个“LastUpdated”时间戳列,并在每次更新时更新(例如,通过触发器自动更新)

答案 4 :(得分:1)

您可以尝试使用PageID读取SQL Server事务日志。

这不是一种保证的方法,但是它在许多情况下都可以工作,并且比查询索引统计信息更准确

/* This is example how to query datetime of data changes using SQL Server 
   transaction log, if audit routine wasn't set */

USE [AdventureWorksDW2017]
GO

UPDATE dbo.FactFinance
SET Date = GETDATE(), Amount = Amount + 1
WHERE FinanceKey = 1
GO

WITH main AS
(   
    SELECT 
        replace(replace(sys.fn_PhysLocFormatter (%%physloc%%), ')', ''), '(', '') page,
        FinanceKey, Date, Amount
    FROM 
        dbo.FactFinance (NOLOCK)   
    WHERE 
        FinanceKey = 1
),
tlog AS
( 
    SELECT 
        page, l2.[Begin Time], L2.[End Time],
        l1.AllocUnitName l1_uname, l2.[Transaction Name] l2_tname,
        l1.[Transaction ID]
    FROM 
        main
    JOIN
        sys.fn_dblog(NULL, NULL) l1 ON PATINDEX('%'+main.page+'%', l1.[Lock Information]) > 0
    LEFT JOIN 
        sys.fn_dblog(NULL, NULL) l2 ON l2.[Transaction ID] = l1.[Transaction ID]  
)
SELECT 
    PAGE, [Transaction ID], 
    MIN([Begin Time]), MIN([End Time]),
    MIN(l1_uname), MIN(l2_tname)
FROM
    tlog
GROUP BY 
    [Transaction ID], page

答案 5 :(得分:-2)

记录上次更新的时间,以及更新后的记录可以通过添加默认值为GetDate()的last_updated列来维护。最后一次更新用户名很棘手,因为您的应用最有可能使用公共数据库连接。可以通过将其作为自定义添加到所有插入和更新过程并传递AD,SSO或登录凭据来填充用户名 - 无论对您的身份验证方法有何意义。

最后一个更新列非常有用且必要,它应作为数据库或至少表的set选项包含在内。为什么?输入事实后,尝试在没有它的情况下获取此信息(提示,如果您有一个身份字段 - 它"可能"帮助,但可能不可靠)。