変更の追跡を使用するアプリケーションは、追跡された変更を取得し、これらの変更を別のデータ ストアに適用し、ソース データベースを更新できる必要があります。 このトピックでは、これらのタスクを実行する方法について説明します。また、フェールオーバーが発生し、データベースをバックアップから復元する必要がある場合に、ロール変更の追跡が果たす役割についても説明します。
変更追跡関数を使用して変更を取得する
変更追跡関数を使用して、データベースに加えられた変更と変更に関する情報を取得する方法について説明します。
変更追跡機能について
アプリケーションでは、次の関数を使用して、データベースに加えられた変更およびその変更に関する情報を取得することができます。
CHANGETABLE(CHANGES ...) 関数
この行セット関数は、変更情報のクエリに使用されます。 この関数は、内部変更追跡テーブルに格納されているデータに対してクエリを実行します。 この関数は、変更された行の主キーと、その行の操作、更新された列、バージョンなどの他の変更情報を含む結果セットを返します。
CHANGETABLE(CHANGES ...) は、最後の同期バージョンを引数として受け取ります。 最後の sychronization バージョンは、 @last_synchronization_version 変数を使用して取得されます。 最後の同期バージョンのセマンティクスは次のとおりです。
呼び出し元のクライアントは変更を取得し、最新の同期バージョンまでのすべての変更を認識します。
したがって、CHANGETABLE(CHANGES ...) は、最後の同期バージョンの後に発生したすべての変更を返します。
次の図は、CHANGETABLE(CHANGES ...) を使用して変更を取得する方法を示しています。
CHANGE_TRACKING_CURRENT_VERSION() 関数
変更を照会するときに次回使用される現在のバージョンを取得するために使用されます。 このバージョンは、最後にコミットされたトランザクションのバージョンを表します。
CHANGE_TRACKING_MIN_VALID_VERSION()関数
クライアントが持つ最小有効バージョンを取得し、CHANGETABLE() から有効な結果を取得するために使用されます。 クライアントは、この関数によって返される値に対して、最後の同期バージョンを確認する必要があります。 最後の同期バージョンがこの関数によって返されるバージョンより小さい場合、クライアントは CHANGETABLE() から有効な結果を取得できず、再初期化する必要があります。
初期データの取得
アプリケーションが初めて変更を取得するには、アプリケーションが最初のデータと同期バージョンを取得するためのクエリを送信する必要があります。 アプリケーションは、テーブルから適切なデータを直接取得し、CHANGE_TRACKING_CURRENT_VERSION() を使用して初期バージョンを取得する必要があります。 このバージョンは、変更が初めて取得された時点で CHANGETABLE(CHANGES ...) に渡されます。
次の例は、初期同期バージョンと初期データ セットを取得する方法を示しています。
-- Obtain the current synchronization version. This will be used next time that changes are obtained.
SET @synchronization_version = CHANGE_TRACKING_CURRENT_VERSION();
-- Obtain initial data set.
SELECT
P.ProductID, P.Name, P.ListPrice
FROM
SalesLT.Product AS P
変更追跡関数を使用して変更を取得する
テーブルの変更された行と変更に関する情報を取得するには、CHANGETABLE(CHANGES...) を使用します。たとえば、次のクエリは、 SalesLT.Product テーブルの変更を取得します。
SELECT
CT.ProductID, CT.SYS_CHANGE_OPERATION,
CT.SYS_CHANGE_COLUMNS, CT.SYS_CHANGE_CONTEXT
FROM
CHANGETABLE(CHANGES SalesLT.Product, @last_synchronization_version) AS CT
通常、クライアントは行の主キーだけでなく、行の最新のデータを取得する必要があります。 そのため、アプリケーションは CHANGETABLE(CHANGES ...) の結果をユーザー テーブル内のデータと結合します。 たとえば、次のクエリでは、 SalesLT.Product テーブルと結合して、 Name 列と ListPrice 列の値を取得します。
OUTER JOINが使用されていることに注意してください。 これは、ユーザー テーブルから削除された行の変更情報が返されるようにするために必要です。
SELECT
CT.ProductID, P.Name, P.ListPrice,
CT.SYS_CHANGE_OPERATION, CT.SYS_CHANGE_COLUMNS,
CT.SYS_CHANGE_CONTEXT
FROM
SalesLT.Product AS P
RIGHT OUTER JOIN
CHANGETABLE(CHANGES SalesLT.Product, @last_synchronization_version) AS CT
ON
P.ProductID = CT.ProductID
次の変更列挙型で使用するバージョンを取得するには、次の例に示すように CHANGE_TRACKING_CURRENT_VERSION() を使用します。
SET @synchronization_version = CHANGE_TRACKING_CURRENT_VERSION()
アプリケーションが変更を取得するときは、次の例に示すように CHANGETABLE(CHANGES...) と CHANGE_TRACKING_CURRENT_VERSION() の両方を使用する必要があります。
-- Obtain the current synchronization version. This will be used the next time CHANGETABLE(CHANGES...) is called.
SET @synchronization_version = CHANGE_TRACKING_CURRENT_VERSION();
-- Obtain incremental changes by using the synchronization version obtained the last time the data was synchronized.
SELECT
CT.ProductID, P.Name, P.ListPrice,
CT.SYS_CHANGE_OPERATION, CT.SYS_CHANGE_COLUMNS,
CT.SYS_CHANGE_CONTEXT
FROM
SalesLT.Product AS P
RIGHT OUTER JOIN
CHANGETABLE(CHANGES SalesLT.Product, @last_synchronization_version) AS CT
ON
P.ProductID = CT.ProductID
バージョン番号
変更追跡が有効になっているデータベースには、変更追跡テーブルに対する変更が行われると増加するバージョン カウンターがあります。 変更された各行には、それに関連付けられているバージョン番号があります。 変更を照会する要求がアプリケーションに送信されると、バージョン番号を提供する関数が呼び出されます。 この関数は、そのバージョン以降に行われたすべての変更に関する情報を返します。 いくつかの点で、変更追跡バージョンの概念は rowversion データ型と似ています。
最終同期バージョンの検証
変更に関する情報は、限られた期間保持されます。 時間の長さは、ALTER DATABASE の一部として指定できるCHANGE_RETENTION パラメーターによって制御されます。
CHANGE_RETENTIONに指定された時間によって、すべてのアプリケーションがデータベースへの変更を要求する必要がある頻度が決まります。 アプリケーションにテーブルの最小有効な同期バージョンより古い last_synchronization_version の値がある場合、そのアプリケーションは有効な変更列挙を実行できません。 これは、一部の変更情報がクリーンアップされた可能性があるためです。 アプリケーションが CHANGETABLE(CHANGES ...) を使用して変更を取得する前に、アプリケーションは CHANGETABLE(CHANGES ...) に渡す予定 のlast_synchronization_version の値を検証する必要があります。 last_synchronization_version の値が無効な場合、そのアプリケーションはすべてのデータを再初期化する必要があります。
次の例は、各テーブルの last_synchronization_version の値の有効性を確認する方法を示しています。
-- Check individual table.
IF (@last_synchronization_version < CHANGE_TRACKING_MIN_VALID_VERSION(
OBJECT_ID('SalesLT.Product')))
BEGIN
-- Handle invalid version and do not enumerate changes.
-- Client must be reinitialized.
END
次の例に示すように、 last_synchronization_version の値の有効性は、データベース内のすべてのテーブルに対して確認できます。
-- Check all tables with change tracking enabled
IF EXISTS (
SELECT COUNT(*) FROM sys.change_tracking_tables
WHERE min_valid_version > @last_synchronization_version )
BEGIN
-- Handle invalid version & do not enumerate changes
-- Client must be reinitialized
END
列追跡の使用
列の追跡を使用すると、アプリケーションは行全体ではなく、変更された列のデータのみを取得できます。 たとえば、テーブルに大きな列が 1 つ以上あるが、ほとんど変更されないシナリオを考えてみましょう。また、頻繁に変更される他の列もあります。 列の追跡を行わないと、アプリケーションは行が変更されたと判断するだけで、大きな列データを含むすべてのデータを同期する必要があります。 ただし、列の追跡を使用すると、アプリケーションは、大きな列データが変更されたかどうかを判断し、変更された場合にのみデータを同期できます。
列追跡情報は、CHANGETABLE(CHANGES ...) 関数によって返されるSYS_CHANGE_COLUMNS列に表示されます。
変更されていない列に対して NULL が返されるように、列追跡を使用できます。 列を NULL に変更できる場合は、列が変更されたかどうかを示す別の列を返す必要があります。
次の例では、その列が変更されなかった場合、 CT_ThumbnailPhoto 列が NULL されます。 この列はNULLに変更されたため、NULLすることもできます。アプリケーションでは、CT_ThumbNailPhoto_Changed列を使用して列が変更されたかどうかを判断できます。
DECLARE @PhotoColumnId int = COLUMNPROPERTY(
OBJECT_ID('SalesLT.Product'),'ThumbNailPhoto', 'ColumnId')
SELECT
CT.ProductID, P.Name, P.ListPrice, -- Always obtain values.
CASE
WHEN CHANGE_TRACKING_IS_COLUMN_IN_MASK(
@PhotoColumnId, CT.SYS_CHANGE_COLUMNS) = 1
THEN ThumbNailPhoto
ELSE NULL
END AS CT_ThumbNailPhoto,
CHANGE_TRACKING_IS_COLUMN_IN_MASK(
@PhotoColumnId, CT.SYS_CHANGE_COLUMNS) AS
CT_ThumbNailPhoto_Changed
CT.SYS_CHANGE_OPERATION, CT.SYS_CHANGE_COLUMNS,
CT.SYS_CHANGE_CONTEXT
FROM
SalesLT.Product AS P
INNER JOIN
CHANGETABLE(CHANGES SalesLT.Product, @last_synchronization_version) AS CT
ON
P.ProductID = CT.ProductID AND
CT.SYS_CHANGE_OPERATION = 'U'
一貫性のある正しい結果の取得
テーブルの変更されたデータを取得するには、複数の手順が必要です。 特定の問題が考慮および処理されない場合は、一貫性のない結果または正しくない結果が返される可能性があることに注意してください。
たとえば、Sales テーブルと SalesOrders テーブルに対して行われた変更を取得するには、アプリケーションで次の手順を実行します。
CHANGE_TRACKING_MIN_VALID_VERSION() を使用して、最後に同期されたバージョンを検証します。
CHANGE_TRACKING_CURRENT_VERSION() を使用して、次回変更を取得するために使用できるバージョンを取得します。
CHANGETABLE(CHANGES ...) を使用して Sales テーブルの変更を取得します。
CHANGETABLE(CHANGES ...) を使用して SalesOrders テーブルの変更を取得します。
前の手順で返される結果に影響を与える可能性がある 2 つのプロセスがデータベースで発生しています。
クリーンアップ プロセスはバックグラウンドで実行され、指定された保持期間より古い変更追跡情報が削除されます。
クリーンアップ プロセスは、データベースの変更追跡を構成するときに指定された保持期間を使用する別のバックグラウンド プロセスです。 問題は、最後の同期バージョンが検証されてから CHANGETABLE(CHANGES...) の呼び出しが行われるまでの間にクリーンアップ プロセスが発生する可能性があるということです。 最後に有効だった同期バージョンは、変更が取得された時点で無効になる可能性があります。 そのため、正しくない結果が返される可能性があります。
Sales テーブルと SalesOrders テーブルでは、次のような DML 操作が進行中です。
CHANGE_TRACKING_CURRENT_VERSION() を使用して、次回のバージョンが取得された後にテーブルに変更を加えることができます。 そのため、予想よりも多くの変更を返すことができます。
トランザクションは、Sales テーブルから変更を取得する呼び出しと、SalesOrders テーブルから変更を取得する呼び出しの間にコミットされる可能性があります。 したがって、SalesOrder テーブルの結果には、Sales テーブルに存在しない外部キー値が含まれている可能性があります。
前述の課題を克服するには、スナップショット分離を使用することをお勧めします。 これにより、変更情報の一貫性を確保し、バックグラウンド クリーンアップ タスクに関連する競合状態を回避できます。 スナップショット トランザクションを使用しない場合、変更の追跡を使用するアプリケーションを開発するには、大幅に多くの労力が必要になる可能性があります。
スナップショット分離の使用
変更の追跡は、スナップショットの分離に対して適切に機能するように設計されています。 データベースに対してスナップショット分離を有効にする必要があります。 変更を取得するために必要なすべての手順は、スナップショット トランザクション内に含める必要があります。 これにより、変更の取得中にデータに加えられたすべての変更が、スナップショット トランザクション内のクエリに表示されなくなります。
スナップショット トランザクション内のデータを取得するには、次の手順を実行します。
トランザクション分離レベルをスナップショットに設定し、トランザクションを開始します。
CHANGE_TRACKING_MIN_VALID_VERSION() を使用して、最後の同期バージョンを検証します。
CHANGE_TRACKING_CURRENT_VERSION() を使用して、次回使用するバージョンを取得します。
CHANGETABLE(CHANGES ...) を使用して Sales テーブルの変更を取得します。
CHANGETABLE(CHANGES ...) を使用して Salesorders テーブルの変更を取得します。
トランザクションをコミットします。
変更を取得するすべての手順はスナップショット トランザクション内に含まれるので、覚えておく必要がある点がいくつかあります。
最後の同期バージョンが検証された後にクリーンアップが行われた場合、クリーンアップによって実行される削除操作はトランザクション内に表示されないため、CHANGETABLE(CHANGES ...) の結果は引き続き有効です。
次の同期バージョンが取得された後に Sales テーブルまたは SalesOrders テーブルに加えられた変更は表示されず、CHANGETABLE(CHANGES ...) の呼び出しでは、CHANGE_TRACKING_CURRENT_VERSION() によって返されたバージョンより後のバージョンの変更は返されません。 SALES テーブルと SalesOrders テーブルの間の整合性も維持されます。これは、CHANGETABLE (CHANGES ...) の呼び出しの間にコミットされたトランザクションは表示されないためです。
次の例は、データベースに対してスナップショット分離を有効にする方法を示しています。
-- The database must be configured to enable snapshot isolation.
ALTER DATABASE AdventureWorksLT
SET ALLOW_SNAPSHOT_ISOLATION ON;
スナップショット トランザクションは次のように使用されます。
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
BEGIN TRAN
-- Verify that version of the previous synchronization is valid.
-- Obtain the version to use next time.
-- Obtain changes.
COMMIT TRAN
スナップショット トランザクションの詳細については、「 SET TRANSACTION ISOLATION LEVEL (Transact-SQL)」を参照してください。
スナップショット分離の使用に代わる方法
スナップショット分離を使用する代わりに方法がありますが、すべてのアプリケーション要件が満たされるようにするには、より多くの作業が必要です。 変更が取得される前に 、last_synchronization_version が有効で、クリーンアップ プロセスによってデータが削除されていないことを確認するには、次の操作を行います。
CHANGETABLE() の呼び出し後に last_synchronization_version を確認します。
CHANGETABLE() を使用して変更を取得するには、各クエリの一部として last_synchronization_version を確認します。
変更は、次の列挙の同期バージョンが取得された後に発生する可能性があります。 この状況を処理する方法は 2 つあります。 使用されるオプションは、アプリケーションと、各アプローチの副作用を処理する方法によって異なります。
新しい同期バージョンより大きいバージョンの変更は無視します。
このアプローチには、副作用として、新しい同期バージョンの前に行が作成または更新され、その後さらに更新された場合に、その行がスキップされることがあります。 新しい行がある場合、スキップされた行を参照する別のテーブルに行が作成された場合、参照整合性の問題が発生する可能性があります。 更新された既存の行がある場合、行はスキップされ、次回まで同期されません。
新しい同期バージョンより大きいバージョンの変更であっても、すべての変更を含めます。
新しい同期バージョンより大きいバージョンの行は、次回の同期時に再度取得されます。 これは、アプリケーションによって想定および処理される必要があります。
前の 2 つのオプションに加えて、操作に応じて両方のオプションを組み合わせたアプローチを考案できます。 たとえば、行が作成または削除された次の同期バージョンよりも新しい変更を無視するのが最適なアプリケーションが必要な場合、更新は無視されません。
注
変更の追跡 (またはカスタム追跡メカニズム) を使用している場合にアプリケーションで機能する方法を選択するには、重要な分析が必要です。 そのため、スナップショット分離を使用する方がはるかに簡単です。
変更追跡でデータベースへの変更を処理する方法
変更の追跡を使用する一部のアプリケーションでは、別のデータ ストアとの双方向同期が実行されます。 つまり、SQL Server データベースで行われた変更は他のデータ ストアで更新され、他のストアで行われた変更は SQL Server データベースで更新されます。
アプリケーションが別のデータ ストアからの変更でローカル データベースを更新する場合、アプリケーションは次の操作を実行する必要があります。
競合がないか確認します。
両方のデータ ストアで同じデータが同時に変更されると、競合が発生します。 アプリケーションは競合を確認し、競合を解決できるように十分な情報を取得できる必要があります。
アプリケーション コンテキスト情報を格納します。
アプリケーションには、変更追跡情報を含むデータが格納されます。 この情報は、ローカル データベースから変更が取得されたときに、他の変更追跡情報と共に使用できます。 このコンテキスト情報の一般的な例は、変更のソースであったデータ ストアの識別子です。
前の操作を実行するために、同期アプリケーションは次の関数を使用できます。
CHANGETABLE(VERSION...)
アプリケーションが変更を行うときは、この関数を使用して競合を確認できます。 この関数は、変更追跡テーブル内の指定された行の最新の変更追跡情報を取得します。 変更追跡情報には、最後に変更された行のバージョンが含まれます。 この情報により、アプリケーションは、アプリケーションが最後に同期された後に行が変更されたかどうかを判断できます。
CHANGE_TRACKING_CONTEXT を使用して
アプリケーションでは、この句を使用してコンテキスト データを格納できます。
競合の確認
双方向同期シナリオでは、クライアント アプリケーションは、アプリケーションが最後に変更を取得してから行が更新されていないかどうかを判断する必要があります。
次の例は、CHANGETABLE(VERSION ...) 関数を使用して、別のクエリを使用せずに、最も効率的な方法で競合をチェックする方法を示しています。 この例では、CHANGETABLE(VERSION ...)は、@product idで指定された行のSYS_CHANGE_VERSIONを決定します。
CHANGETABLE(CHANGES ...) は同じ情報を取得できますが、効率は低下します。 行の SYS_CHANGE_VERSION の値が @last_sync_versionの値より大きい場合、競合が発生します。 競合がある場合、行は更新されません。 行に変更情報がない可能性があるため、 ISNULL() チェックが必要です。 変更の追跡が有効になってから、または変更情報がクリーンアップされてから行が更新されていない場合、変更情報は存在しません。
-- Assumption: @last_sync_version has been validated.
UPDATE
SalesLT.Product
SET
ListPrice = @new_listprice
FROM
SalesLT.Product AS P
WHERE
ProductID = @product_id AND
@last_sync_version >= ISNULL (
SELECT CT.SYS_CHANGE_VERSION
FROM CHANGETABLE(VERSION SalesLT.Product,
(ProductID), (P.ProductID)) AS CT),
0)
次のコードでは、更新された行数を確認し、競合に関する詳細情報を特定できます。
-- If the change cannot be made, find out more information.
IF (@@ROWCOUNT = 0)
BEGIN
-- Obtain the complete change information for the row.
SELECT
CT.SYS_CHANGE_VERSION, CT.SYS_CHANGE_CREATION_VERSION,
CT.SYS_CHANGE_OPERATION, CT.SYS_CHANGE_COLUMNS
FROM
CHANGETABLE(CHANGES SalesLT.Product, @last_sync_version) AS CT
WHERE
CT.ProductID = @product_id;
-- Check CT.SYS_CHANGE_VERSION to verify that it really was a conflict.
-- Check CT.SYS_CHANGE_OPERATION to determine the type of conflict:
-- update-update or update-delete.
-- The row that is specified by @product_id might no longer exist
-- if it has been deleted.
END
コンテキスト情報の設定
WITH CHANGE_TRACKING_CONTEXT 句を使用すると、アプリケーションはコンテキスト情報を変更情報と共に格納できます。 この情報は、CHANGETABLE(CHANGES ...) によって返されるSYS_CHANGE_CONTEXT列から取得できます。
コンテキスト情報は、通常、変更のソースを識別するために使用されます。 変更のソースを特定できる場合は、再同期時に変更を取得しないように、データ ストアでその情報を使用できます。
-- Try to update the row and check for a conflict.
WITH CHANGE_TRACKING_CONTEXT (@source_id)
UPDATE
SalesLT.Product
SET
ListPrice = @new_listprice
FROM
SalesLT.Product AS P
WHERE
ProductID = @product_id AND
@last_sync_version >= ISNULL (
(SELECT CT.SYS_CHANGE_VERSION FROM CHANGETABLE(VERSION SalesLT.Product,
(ProductID), (P.ProductID)) AS CT),
0)
一貫性のある正しい結果を確保する
アプリケーションは、 @last_sync_versionの値を検証するときにクリーンアップ プロセスを考慮する必要があります。 これは、CHANGE_TRACKING_MIN_VALID_VERSION() が呼び出された後、更新が行われる前にデータが削除された可能性があるためです。
重要
スナップショット分離を使用し、スナップショット トランザクション内で変更を行うことをお勧めします。
-- Prerequisite is to ensure ALLOW_SNAPSHOT_ISOLATION is ON for the database.
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
BEGIN TRAN
-- Verify that last_sync_version is valid.
IF (@last_sync_version <
CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID('SalesLT.Product')))
BEGIN
RAISERROR (N'Last_sync_version too old', 16, -1);
END
ELSE
BEGIN
-- Try to update the row.
-- Check @@ROWCOUNT and check for a conflict.
END
COMMIT TRAN
注
スナップショット トランザクションの開始後に、スナップショット トランザクション内で更新されている行が別のトランザクションで更新された可能性があります。 この場合、スナップショット分離更新の競合が発生し、トランザクションが終了します。 この場合は、更新を再試行してください。 これにより、変更追跡の競合が検出され、行は変更されません。
変更の追跡とデータの復元
同期を必要とするアプリケーションでは、変更の追跡が有効になっているデータベースが以前のバージョンのデータに戻る場合を考慮する必要があります。 これは、データベースがバックアップから復元された後、非同期データベース ミラーへのフェールオーバーがある場合、またはログ配布を使用するときにエラーが発生した場合に発生する可能性があります。 次のシナリオは、この問題を示しています。
テーブル T1 は変更追跡され、テーブルの最小有効バージョンは 50 です。
クライアント アプリケーションは、バージョン 100 でデータを同期し、バージョン 50 と 100 の間のすべての変更に関する情報を取得します。
バージョン 100 以降、テーブル T1 に対して追加の変更が行われます。
バージョン 120 ではエラーが発生し、データベース管理者はデータ損失でデータベースを復元します。 復元操作の後、テーブルにはバージョン 70 までのデータが含まれており、同期される最小バージョンは 50 のままです。
これは、同期されたデータ ストアに、プライマリ データ ストアに存在しなくなったデータがあることを意味します。
T1 は何度も更新されます。 これにより、現在のバージョンが 130 に設定されます。
クライアント アプリケーションが再び同期され、最後に同期されたバージョンの 100 が提供されます。 100 が 50 より大きいため、クライアントはこの数値を正常に検証します。
クライアントは、バージョン 100 と 130 の間の変更を取得します。 この時点で、クライアントは、70 から 100 の間の変更が以前と同じではないことを認識していません。 クライアントとサーバー上のデータは同期されません。
データベースがバージョン 100 より後の時点に復旧された場合、同期に問題は発生しないことに注意してください。 クライアントとサーバーは、次の同期期間中にデータを正しく同期します。
変更の追跡では、データの損失からの回復はサポートされません。 ただし、これらの種類の同期の問題を検出するには、次の 2 つのオプションがあります。
データベースのバージョン ID をサーバーに格納し、データベースが復旧されるか、データが失われるたびにこの値を更新します。 各クライアント アプリケーションは ID を格納し、各クライアントはデータを同期するときにこの ID を検証する必要があります。 データ損失が発生した場合、ID は一致せず、クライアントは再初期化されます。 1 つの欠点は、データ損失が最後に同期された境界を越えていなかった場合、クライアントが不要な再初期化を行うことです。
クライアントが変更を照会する場合は、サーバー上の各クライアントの最後の同期バージョン番号を記録します。 データに問題がある場合、最後に同期されたバージョン番号は一致しません。 これは、再初期化が必要であることを示します。
こちらもご覧ください
データ変更の追跡 (SQL Server)
変更の追跡について (SQL Server)
変更の追跡の管理 (SQL Server)
変更履歴の有効化と無効化 (SQL Server)
CHANGETABLE (Transact-SQL)
CHANGE_TRACKING_MIN_VALID_VERSION(Transact-SQL)
CHANGE_TRACKING_CURRENT_VERSION (Transact-SQL)
変更追跡コンテキスト設定 (Transact-SQL)