Проверьте изменения в таблицу SQL Server?

голоса
122

Как я могу контролировать базу данных сервера SQL для изменения в таблицу без использования триггеров или изменения структуры базы данных каким - либо образом? Я предпочитаю среды программирования .NET и C #.

Я хотел бы быть в состоянии поддерживать любой SQL Server 2000 SP4 или более позднюю версию. Моя заявка на болты визуализации данных для продукта другой компании. Наша клиентская база в тысячах, так что я не хочу , чтобы положить в требования , которые мы модифицируем таблицу стороннего поставщика на каждую установке.

К «изменениям в таблицу» Я имею в виду изменений в данную таблицу, а не изменения в структуру таблицы.

В конце концов, я хотел бы изменения, чтобы вызвать событие в моем приложении, вместо того, чтобы проверить изменения в интервале.


Лучший курс действий , учитывая мои требования (нет триггеров или изменения схемы, SQL Server 2000 и 2005) , кажется , чтобы использовать BINARY_CHECKSUMфункцию в T-SQL . Как я планирую осуществить это:

Каждые Х секунд выполнить следующий запрос:

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*))
FROM sample_table
WITH (NOLOCK);

И сравните это с сохраненным значением. Если значение изменилось, пройти через строку таблицы с помощью запроса:

SELECT row_id, BINARY_CHECKSUM(*)
FROM sample_table
WITH (NOLOCK);

И сравните возвращенные контрольные суммы с сохраненными значениями.

Задан 01/08/2008 в 13:35
источник пользователем
На других языках...                            


8 ответов

голоса
90

Посмотрите на команду CHECKSUM:

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM sample_table WITH (NOLOCK);

Это будет возвращать один и тот же номер каждый раз, когда он работать до тех пор, как содержимое таблицы не изменилось. См мой пост на этом для получения дополнительной информации:

СУММА

Вот как я использовал его для восстановления зависимостей кэша , когда таблица изменилась:
зависимость ASP.NET кэша базы данных 1.1 (без триггеров)

Ответил 02/08/2008 в 06:20
источник пользователем

голоса
30

К сожалению CHECKSUM не работает всегда правильно , чтобы обнаружить изменения . Это лишь примитивная контрольная сумма и не вычисление CRC. Поэтому вы не можете использовать его , чтобы обнаружить все изменения, например , симметричные изменения приводят к одной и той же CHECKSUM!

Е. г. решение с CHECKSUM_AGG(BINARY_CHECKSUM(*))обеспечивает всегда 0 для всех 3 -х таблиц с различным содержанием!


SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM 
(
  SELECT 1 as numA, 1 as numB
  UNION ALL
  SELECT 1 as numA, 1 as numB
)  q
-- delivers 0!

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM ( SELECT 1 as numA, 2 as numB UNION ALL SELECT 1 as numA, 2 as numB ) q -- delivers 0!

SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) FROM ( SELECT 0 as numA, 0 as numB UNION ALL SELECT 0 as numA, 0 as numB ) q -- delivers 0!

Ответил 30/03/2011 в 13:07
источник пользователем

голоса
25

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

Ответил 01/08/2008 в 14:07
источник пользователем

голоса
19

Как часто вам нужно проверить изменения и насколько велики (с точки зрения размера строки) являются таблицы в базе данных? Если используется CHECKSUM_AGG(BINARY_CHECKSUM(*))метод , предложенный Джоном, он будет сканировать все строки указанной таблицы. NOLOCKПодсказка помогает, но на большой базе данных, вы все еще ударять каждую строку. Вам также нужно хранить контрольную сумму для каждой строки , так что вы говорите один изменился.

Рассматривали ли вы собираетесь на это под другим углом? Если вы не хотите, чтобы изменить схему добавить триггеров, (что делает чувство, это не база данных), Рассматривали ли вы работать с поставщиком приложения, что делает базу данных?

Они могли бы реализовать API, который предоставляет механизм уведомления вспомогательных приложений, что данные изменились. Это может быть столь же просто, как запись в таблицу уведомлений, в котором перечислены какие таблицы и какие строки были изменены. Это может быть реализовано с помощью триггеров или кода приложения. С вашей стороны, ти не имеет значения, ваша единственная забота будет сканировать таблицу уведомлений на периодической основе. Производительность ударила по базе данных будет гораздо меньше, чем сканирование каждой строки для изменения.

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

Ответил 03/08/2008 в 14:59
источник пользователем

голоса
18

Иметь работу DTS (или задание , которое запускается с помощью службы Windows) , которая работает в заданном интервале. Каждый раз , когда он запускается, он получает информацию о данной таблице с помощью системы INFORMATION_SCHEMA таблиц, а также записывает эти данные в хранилище данных. Сравните данные , возвращенные в отношении структуры таблицы с данными возвращается в предыдущий раз. Если она отличается, то вы знаете , что структура изменилась.

Пример запроса, чтобы возвратить информацию относительно всех столбцов в таблице ABC (в идеале пречисление только столбцы из таблицы information_schema, что вы хотите, вместо того, чтобы использовать * выберите ** как я здесь):

select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'ABC'

Вы бы контролировать различные столбцы и представления INFORMATION_SCHEMA в зависимости от того, как именно вы определяете «изменения в таблицу».

Ответил 01/08/2008 в 15:06
источник пользователем

голоса
17

К сожалению, я не думаю , что есть чистый способ сделать это в SQL2000. Если сузить требования к SQL Server 2005 (и более поздних версий), то вы находитесь в бизнесе. Вы можете использовать SQLDependencyкласс в System.Data.SqlClient. См уведомления о запросах в SQL Server (ADO.NET) .

Ответил 06/08/2008 в 02:54
источник пользователем

голоса
13

Дикий догадка: Если вы не хотите вносить изменения в таблицы третьей партии, Вы можете создать представление, а затем поставить курок на этой точке зрения?

Ответил 05/08/2008 в 02:12
источник пользователем

голоса
7

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

Ответил 24/07/2014 в 05:58
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more