2009-08-04 2 views
5

не дублирует my previous questionКак получить последнее время вставки/обновления/удаления datetime на Sql Server 2005?

Есть ли способ, чтобы получить последнюю DateTime, когда таблица/базы данных были вставки/обновления/удаления на Sql Server 2005? Предпочтительно без создания триггеров.

Я знаю, что когда вам нужно последнее обновление для каждой строки, вам нужны триггеры. Но я не уверен, нужны ли они, когда вы просто хотите получить последнее обновление для всей таблицы.

+1

Ответ вы приняли вводит в заблуждение в лучшем случае. –

ответ

8

Вы можете легко получить последнюю вставленную/Обновленные/Deleted Даты следующим образом:

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 [email protected] 
     ORDER BY LASTUPDATED DESC 
    END 
RETURN 

END 



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

Вы можете запустить внутренний оператор Select, если у вас нет администратора или повышенного разрешения, и вы все равно получите свои результаты. Отличное решение. –

+1

Mayeb Я что-то пропустил, но в SQL-SERVER 2008 это не показывает никаких изменений в 'LASTUPDATED', если строки были вставлены/обновлены/удалены. Только при изменении структуры таблицы (добавлены столбцы/индексы и т. Д.). это то, что предназначалось ОП? – ZigiZ

+0

@ZigiZ: Возможно, вы сбиваете с толку столбец 'sys.objects.modify_date', который для таблиц показывает последнюю дату изменения структуры. Значения в столбце 'LASTUPDATED' в этом коде основаны на результатах функции [' STATS_DATE'] (http://technet.microsoft.com/en-us/library/ms190330.aspx) STATS_DATE (Transact-SQL) "). –

2

Учитывая нет ответов, вот мои 2 цента:

  • Для вставки, я хотел бы использовать поле DateTime со значением по умолчанию GETDATE()
  • Для обновления, я хотел бы использовать также DateTime поле, измененное триггером, каждый раз, когда происходит обновление.
  • Для удаления запись будет недоступна, поэтому вы не можете ее запросить.

Я думал об использовании временных меток для запуска триггеров, но вы не можете преобразовать отметки времени в Datetime.

EDIT: Или может быть, вы можете использовать «метатаблицу», где в триггерах вы сохраните изменения даты

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 

Я надеюсь, что это будет полезно

+1

просто следите за блокировкой. Если у вас одновременно есть несколько транзакций, которые изменяют одну и ту же таблицу (разные строки, которые не могут вызвать блокировку), им придется ждать своей очереди, чтобы обновить одну таблицу таблицы журналов для этой таблицы. –

+0

Да, вы правы, не могли бы вы изменить код, чтобы он отражал изменения, которые вы упомянули? я не буду беспокоиться о том, что –

1

без триггеров: вы могли бы иметь LastChgDate столбец таблицы и установите его, когда вы вставляете/обновляете/удаляете строку. Вам придется «удалить», используя столбец состояния, установленный в «D» или что-то в этом роде. Поместите индекс в этот столбец и выберите MAX(), чтобы увидеть, когда было сделано изменение.

+0

просто должен быть ясен, LastChgDate будет типом datetime, и вам нужно будет установить его в GETDATE() для каждого INSERT/UPDATE. Кроме того, «DELETE» будет обрабатываться как UPDATE с изменением статуса на «D» и затем может быть запрошено для последнего времени изменения. –

+0

Перемещение между таблицей журналов и столбцом datetime в фактической таблице кажется громоздким. –

1

Ну, вы можете сохранить столбец с «LastUpdateDate», который установлен на текущую дату/время сервера для любой вставки или обновления. Затем вы можете просто запросить строку с последним LastUpdateDate.

5

Как показывают предыдущие два ответа, в SQL Server нет встроенных функций, которые легко доступны для ваших требований.

Существует тонна динамических видов управления, которые могут рассказать вам некоторые из ваших точек интереса, например. sys.dm_db_index_usage_stats, который сообщает вам, когда данный индекс получил последний запрос или обновление.

Но в коробке действительно нет ничего, что вы могли бы использовать для получения всей информации, которую вы ищете, - вам действительно нужно сделать это самостоятельно, добавив, например, datetime для ваших таблиц и заполнения их триггерами.

Извините, я не могу дать вам лучшую новость - это так, как сейчас.

В SQL Server 2008, у вас есть дополнительные новые возможности, которые могли бы покрыть некоторые из ваших требований - проверить:

Марк

2

За короткий периоды (с момента запуска сервера) вы проверяете sys.dm_db_index_usage_stats last_user_update column. Но поскольку это только учитывает обновления с момента запуска сервера, его нельзя использовать в течение длительного периода времени.

В течение длительных периодов времени, если стол не огромен, ваше приложение может хранить таблицу CHECKSUM_AGG(ALL). Вам нужно будет только повторить этот раз, при запуске приложения и сравнить его с ранее сохраненным значением. Кроме того, приложение может обнаруживать изменения с помощью DMV. При завершении работы приложения она должна хранить текущую контрольную сумму таблицы.

0

Простой! Сначала добавьте столбец «LastUpdated». Дайте ему значение по умолчанию для GetDate(). Это позаботится о вставках. Во-вторых, добавьте триггер обновления обновлений, который обновляет LastUpdated до GetDate(). Обновления теперь охвачены. Наконец, добавьте бит/логическое поле IsDeleted со значением по умолчанию 0. Если пользователь хочет удалить строку, переверните бит. Поскольку, когда вы «удаляете» строку, вы фактически обновляете поле IsDeleted (и, следовательно, используете действие «Обновление»), «Deletes» теперь имеют временную метку.

Чтобы получить самую последнюю активность на столе: только получить временную метку:

SELECT MAX(LastUpdated) FROM MyTable 

Чтобы получить более подробную информацию:

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

Конечно, если вы добавите поле бит ISDeleted, весь существующий код нужно будет переделать, чтобы убедиться, что удаленные записи не используются в запросы. – HLGEM

+0

Конечно, это не будет безболезненно, но он покажет последнее действие на столе, независимо от того, что это было. – Pulsehead

1

Я хотел бы добавить отслеживания изменений в микс - в в отличие от Change Data Capture, это не функция Enterprise.

Читайте об этом в http://msdn.microsoft.com/en-us/library/cc280462.aspx

Подобно sys.dm_db_index_usage_stats, данные не там навсегда (хотя он выживает сервер перезагружается и настраивается), и вы должны извлечь и сохраняться определенная часть информации, которую вы находясь в поиске.

MDD

12
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() 
Смежные вопросы