Как получить дату последней вставки / обновления / удаления на Sql Server 2005? - PullRequest
7 голосов
/ 04 августа 2009

не дубликат моего предыдущего вопроса

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

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

Ответы [ 9 ]

14 голосов
/ 31 октября 2012
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() 
8 голосов
/ 08 ноября 2012

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

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')
6 голосов
/ 04 августа 2009

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

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

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

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

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

Марк

3 голосов
/ 04 августа 2009

Поскольку пока нет ответов, вот мои 2 цента:

  • Для вставки я бы использовал поле DateTime со значением по умолчанию GETDATE ()
  • Для обновления я бы также использовал поле 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

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

2 голосов
/ 04 августа 2009

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

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

1 голос
/ 05 августа 2009

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

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

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

MDD

1 голос
/ 04 августа 2009

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

1 голос
/ 04 августа 2009

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

0 голосов
/ 04 августа 2009

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

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

SELECT MAX(LastUpdated) FROM MyTable

Для получения дополнительной информации:

SELECT MAX(LastUpdated), ID /*or whatever you need to know*/ FROM MyTable
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...