This seems like it should be trivial, but I'm stuck after checking the CREATE TRIGGER docs. No select trigger.
I have a table:
CREATE TABLE [Fileserver].[Files]
(
[FileId] [int] IDENTITY(1, 1) NOT NULL ,
[DateAccessed] [datetime] NULL ,
[DateCreated] [datetime] NULL ,
[DateModified] [datetime] NULL
)
GO
When someone reads a row from the table, I want to update the DateAccessed column. DateCreated is handled with a default value of getdate(), and DateModified with a trigger. I cannot think of a way to handle DateAccessed WITHOUT limiting table access to a stored procedure. Our team is making heavy use of Linq2Sql, so I prefer to allow SQL selects on the table.
Thanks!
You can use SQL Server Audit or manage your own auditing by controlling data access via stored procedures. But think about this... when you run a query that returns the whole table or a large portion of it, do you really want to touch every single row and update it with the current time, just because it was part of the result? Does it really matter that row 1 was read more recently than row 2? If you don't have the "who" with it as well, how valuable is that information?
Seems more appropriate to monitor reads at the table level rather than the row level. You forgot to mention what version of SQL Server you are using, but from SQL Server 2005 and up, you can use sys.dm_db_index_usage_stats
, e.g.
SELECT last_user_seek, last_user_scan, last_user_lookup
FROM sys.dm_db_index_usage_stats
WHERE [object_id] = OBJECT_ID('[Fileserver].[Files]');
If you really need per-row information, as @gbn suggests, there is no free way to do this. You need to log the selects yourself or enable SQL Server Audit. Again, not much of a suggestion because you didn't specify your version; this feature was introduced in SQL Server 2008.
精彩评论