Как создать запрос, который получает только данные, которые были обновлены в таблице

Я понятия не имею, с чего начать или как это будет работать, и я надеюсь, что у кого-то есть идея или проверенный метод.

Чтобы показать пример того, что я пытаюсь сделать, я создал хранимую процедуру, которая UPDATES или INSERT создает новые записи в локальной таблице, получая записи из таблицы ссылок. Хранимая процедура выполняется как задание в SQL Server для обновления и вставки новых записей.

Мой вопрос: есть ли способ запросить данные в локальной таблице, чтобы изначально я мог получить все записи, а не получать только новые записи, которые были вставлены, или старые записи, которые обновляются?

Я не хочу постоянно получать все записи, просто добавленные новые записи или обновленные записи.

Это возможно?

Вот хранимая процедура, которую я создал в качестве примера для обновления данных локального телефона:

CREATE PROCEDURE sp_UPDATE_PHONE_RECORDS AS BEGIN MERGE dbo.PHONE_REC AS Target USING (SELECT MEMBER_ID ,HOME_PHONE = dbo.udf_StdPhoneFmt(HOME) ,CELL_PHONE = dbo.udf_StdPhoneFmt(CELL) ,WORK_PHONE = dbo.udf_StdPhoneFmt(WORK) FROM PHONE WHERE MEMBER_ID IS NOT NULL) AS SOURCE ON (Target.MEMBER_ID = SOURCE.MEMBER_ID) WHEN MATCHED THEN UPDATE SET Target.HOME_PHONE = Source.HOME_PHONE,Target.CELL_PHONE = Source.CELL_PHONE, Target.WORK_PHONE = Source.WORK_PHONE WHEN NOT MATCHED BY TARGET THEN INSERT (MEMBER_ID, HOME_PHONE, CELL_PHONE ,WORK_PHONE) VALUES (Source.MEMBER_ID, Source.HOME_PHONE, Source.CELL_PHONE, Source.WORK_PHONE); END GO 

Это возможно?

Всем спасибо!

Обычно мы добавляем два поля даты / времени в исходную таблицу, например Source.LastModifiedOn и Source.CreatedOn.

Затем, когда задание выполняется, чтобы обновить целевую таблицу, вы можете сказать, что я получаю все строки Source.LastModifiedOn и Source.CreatedOn с момента последнего запуска задания и выполнения ваших обновлений / вставок на основе строк.

Конечно, вы должны быть уверены, что Source.LastModifiedOn и Source.CreatedOn настроены правильно.

Я бы использовал предложение OUTPUT с столбцом $action :

 DECLARE @Target TABLE ( Id INT NOT NULL, Value VARCHAR(10) NULL ); INSERT @Target VALUES (1, 'A'), (2, NULL), (3, NULL); DECLARE @Source TABLE ( Id INT NOT NULL, Value VARCHAR(10) NULL ); INSERT @Source VALUES (2, 'B'), (4, 'D'), (5, 'E'); DECLARE @AffectedRows TABLE ( MergeAction NVARCHAR(10) NOT NULL, Old_Id INT NULL, Old_Value VARCHAR(10) NULL, New_Id INT NULL, New_Value VARCHAR(10) NULL ); MERGE @Target t USING @Source s ON t.Id = s.Id WHEN MATCHED THEN UPDATE SET Value = s.Value WHEN NOT MATCHED THEN INSERT (Id, Value) VALUES (s.Id, s.Value) OUTPUT $action, deleted.Id, deleted.Value, inserted.Id, inserted.Value INTO @AffectedRows(MergeAction, Old_Id, Old_Value, New_Id, New_Value); SELECT * FROM @Target; SELECT * FROM @AffectedRows; 

Результаты:

 Id Value -- ----- 1 A 2 B <-- updated row 3 NULL 4 D <-- inserted row 5 E <-- inserted row MergeAction Old_Id Old_Value New_Id New_Value ----------- ----------- ---------- ----------- --------- INSERT NULL NULL 4 D INSERT NULL NULL 5 E UPDATE 2 NULL 2 B 

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

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

Я просто добавляю одно bit поле с modified значением по умолчанию 1.
Если в таблицу вставляется новая строка, то она автоматически modified на 1.
Если существующая строка обновлена, я должен убедиться, что modified равно 1.

Таким образом, задание нужно искать только для всех строк с modified = 1 .
Не нужно отслеживать дату / время, когда работа была выполнена в последний раз.

Когда задание выполнено успешно, последнее, что он делает, это «сброс» modified поля во всех строках:

 update TheTable set modified = 0 

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

Но он имеет тот же недостаток, что и подход «LastModifiedOn / CreatedOn» от RDotLee – вам нужно убедиться, что каждое обновление в таблице действительно устанавливает modified столбец в 1, поэтому вы можете использовать его только в том случае, если вы контролируете весь код который записывается в таблицу.

TimeStamp

TimeStamp увеличивается и вставляет или обновляет.

На Мастере сделайте это TimeStamp и на Slave сделайте его двоичным (8)

 select [timeStampSlave].* from [timeStampSlave] join [timeStampMaster] on [timeStampSlave].[ID] = [timeStampMaster].ID and [timeStampSlave].[timeStamp] < [timeStampMaster].[timestamp] 

Чтобы запросить серверы, вы можете использовать следующий синтаксис

 [MasterSever].[test].[dbo].[timeStampMaster] 
Давайте будем гением компьютера.