Its a nice script, I have a question wont scheduled Index Maintenance plans have the effect of showing up in the last_user_update?
You could also change the nested CTE to simply be
Select db_name(database_id),Max(x.Last_Date) Last_Access_time
From
sys.dm_db_index_usage_stats
CROSS APPLY(VALUES(last_user_update),(last_user_lookup),(last_user_scan),(last_user_seek)) x (last_date)
Where last_date is NOT NULL
AND db_name(database_id) not in ('msdb','master','tempdb')
group by database_id
Drop that into a single CTE for use as the source for the merge and you should be good to go, all you then have to do is the date diff on the merge.
I would also look at adding a clause to the WHEN MATCHED to only update those rows where the Last_Access_Time is different
So the code reads
;With Cte_Src(
Select
db_name(database_id) databasename
,Max(x.Last_Date) Last_Access_time
,GETDATE() curr_time
From
sys.dm_db_index_usage_stats
CROSS APPLY(VALUES(last_user_update)
,(last_user_lookup)
,(last_user_scan)
,(last_user_seek)) x (last_date)
Where last_date is NOT NULL
AND db_name(database_id) not in ('msdb','master','tempdb')
group by database_id
)
MERGE master..AuditTable AS tgt
USING Cte_Src AS src
ON tgt.databasename = src.databasename
WHEN MATCHED AND src.Last_Access_time != tgt.Last_Access_time
THEN
UPDATE SET
tgt.last_access_time = src.last_access_time
, tgt.no_of_days = DateDiff(d,src.last_access_time, src.curr_time)
, tgt.last_upd_dtm = src.curr_time
WHEN NOT MATCHED BY TARGET
THEN
INSERT (DatabaseName,last_access_time,no_of_days,last_upd_dtm)
VALUES ( src.DatabaseName,src.last_access_time,DateDiff(d,src.last_access_time, src.curr_time));
It needs testing.
One last thing user objects should not be in the Master DB, I would create a centralised Audit Database or a specialised DBA database on each server to hold this type of thing as all you are doing is clutering up the Master DB.
(code reformated)
_________________________________________________________________________
SSC Guide to Posting and Best Practices