<cdc.fn_cdc_get_net_changes_capture_instance> (Transact-SQL)
適用於:SQL Server
針對指定之記錄序號 (LSN) 範圍內變更的每個來源數據列,傳回一個凈變更數據列。
等一下,什麼是 LSN? SQL Server 事務歷史記錄中的每個記錄都會以記錄序號 (LSN) 唯一識別。 LSN 的排序方式是,如果 LSN2 大於 LSN1,則 LSN2 所參考的記錄檔記錄所描述的變更發生在 記錄檔記錄 LSN 所描述的變更之後 。
記錄檔記錄的 LSN,其中發生重大事件有助於建構正確的還原順序。 因為 LSN 已排序,因此您可以比較它們是否相等和不等(也就是 <、、 >=、 <=、 >=)。 建構還原順序時,這類比較很有用。
當來源數據列在 LSN 範圍期間有多個變更時,列舉函式會傳回反映數據列最終內容的單一數據列。 例如,如果交易在源數據表中插入數據列,而 LSN 範圍內的後續交易會更新該數據列中的一或多個數據行,則此函式只會 傳回一個 數據列,其中包含更新的數據行值。
當源數據表啟用異動數據擷取和指定Net追蹤時,就會建立此列舉函數。 若要啟用網路追蹤,源數據表必須具有主鍵或唯一索引。 函式名稱是衍生的,並使用 格式 cdc.fn_cdc_get_net_changes_<capture_instance>
,其中 <capture_instance> 是啟用異動數據擷取時,針對擷取實例指定的值。 如需詳細資訊,請參閱 sys.sp_cdc_enable_table (Transact-SQL) 。
語法
cdc.fn_cdc_get_net_changes_capture_instance ( from_lsn , to_lsn , '<row_filter_option>' )
<row_filter_option> ::=
{ all
| all with mask
| all with merge
}
引數
from_lsn
LSN,表示要包含在結果集中之 LSN 範圍的低端點。 from_lsn為 binary(10)。
只有 cdc 中的數據 列。[capture_instance]_CT 在結果集中包含值 __$start_lsn大於或等於 from_lsn 的變更數據表。
to_lsn
LSN,表示要包含在結果集中之 LSN 範圍的高端點。 to_lsn為 binary(10)。
只有 cdc 中的數據列。[capture_instance]_CT在 __$start_lsn 小於或等於from_lsn或等於to_lsn的值變更數據表會包含在結果集中。
<> row_filter_option ::= { all | all with mask | all with merge }
選項,可控管元數據行的內容,以及結果集中傳回的數據列。 可以是下列其中一個選項:
全部
傳回數據列最後變更的 LSN,以及在元數據行 __$start_lsn 和 __$operation 中套用數據列所需的作業。 數據行 __$update_mask一律為 NULL。
全部含遮罩
傳回數據列最後變更的 LSN,以及在元數據行 __$start_lsn 和 __$operation 中套用數據列所需的作業。 此外,當更新作業傳回 (__$operation = 4) 更新中修改的擷取數據行會在 __$update_mask 傳回的值中標示。
全部合併
傳回元數據行 __$start_lsn中數據列之最終變更的 LSN。 數據行 __$operation 將是兩個值之一:1 用於刪除,5 表示套用變更所需的作業是插入或更新。 數據行 __$update_mask一律為 NULL。
因為判斷指定變更的精確作業的邏輯會增加查詢複雜性,所以這個選項的設計目的是為了在足以指出套用變更數據所需的作業是插入或更新時改善查詢效能,但不需要明確區分這兩者。 此選項在直接提供合併作業的目標環境中最具吸引力。
傳回的資料表
資料行名稱 | 資料類型 | 描述 |
---|---|---|
__$start_lsn | binary(10) | 與變更之認可交易相關聯的 LSN。 在相同交易中認可的所有變更都會共用相同的認可 LSN。 例如,如果源數據表上的更新作業修改兩個數據列中的兩個數據行,則變更數據表會包含四個數據列,每個數據列都有相同的 __$start_lsnvalue。 |
__$operation | int | 識別將變更數據列套用至目標數據源所需的數據操作語言 (DML) 作業。 如果 row_filter_option 參數的值全部或全部為mask,則此資料列中的值可以是下列其中一個值: 1 = 刪除 2 = 插入 4 = update 如果row_filter_option參數的值全都與合併,則此數據行中的值可以是下列其中一個值: 1 = 刪除 5 = 插入或更新 |
__$update_mask | varbinary(128) | 位遮罩,其位對應至針對擷取實例識別的每個擷取數據行。 當 __$operation = 1 或 2 時,這個值已將所有定義的位設定為 1。 當 __$operation = 3 或 4 時,只有對應至已變更之數據行的位會設定為 1。 |
<擷取的來源資料表資料行> | 視情況而異 | 這個函數所傳回的其餘資料行都是建立擷取執行個體時,在來源資料表中識別成擷取資料行的資料行。 如果未在擷取的數據行清單中指定任何數據行,則會傳回源數據表中的所有數據行。 |
權限
需要系統管理員固定伺服器角色的成員資格,或db_owner固定資料庫角色的成員資格。 對於所有其他使用者,需要源數據表中所有擷取數據行的SELECT許可權,如果已定義擷取實例的管制角色,該資料庫角色的成員資格。 當呼叫端沒有檢視源數據的許可權時,函式會傳回所有數據行具有NULL值的數據列。
備註
修改數據列的唯一標識符會導致 fn_cdc_get_net_changes
使用 DELETE 顯示初始 UPDATE 命令,然後改為 INSERT 命令。 此行為必須同時追蹤變更前後的索引鍵。
如果呼叫 或 cdc.fn_cdc_get_net_changes_<capture_instance>
時cdc.fn_cdc_get_all_changes_<capture_instance>
提供的 LSN 範圍不適合,則預期會發生錯誤 313。 lsn_value
如果 參數超出最低 LSN 或最高 LSN 的時間,則執行這些函式將會傳回錯誤 313:Msg 313, Level 16, State 3, Line 1 An insufficient number of arguments were supplied for the procedure or function
。 開發人員應該處理此錯誤。
範例
下列範例會使用 函 cdc.fn_cdc_get_net_changes_HR_Department
式,在特定時間間隔內報告對源數據表 HumanResources.Department
所做的凈變更。
首先,函 GETDATE
式是用來標記時間間隔的開頭。 將數個 DML 語句套用至源數據表之後,會再次呼叫 函 GETDATE
式來識別時間間隔的結尾。 然後,函式sys.fn_cdc_map_time_to_lsn用來將時間間隔對應至 LSN 值所系結的異動數據擷取查詢範圍。 最後,會查詢函 cdc.fn_cdc_get_net_changes_HR_Department
式,以取得時間間隔源數據表的凈變更。 請注意,插入后刪除的數據列不會出現在函式所傳回的結果集中。 這是因為第一次新增並在查詢視窗中刪除的數據列在源數據表上不會產生間隔的凈變更。
注意
執行此範例之前,您必須先在 sys.sp_cdc_enable_table (Transact-SQL) 中執行範例 B,才能在數據表HumanResources.Department
上啟用 CDC。 在下列範例中,HR_Department是 CDC 擷取實例的名稱,如 中所 sys.sp_cdc_enable_table
指定。
USE AdventureWorks2022;
GO
DECLARE @begin_time datetime, @end_time datetime, @from_lsn binary(10), @to_lsn binary(10);
-- Obtain the beginning of the time interval.
SET @begin_time = DATEADD(day, -1, GETDATE()) ;
-- DML statements to produce changes in the HumanResources.Department table.
INSERT INTO HumanResources.Department (Name, GroupName)
VALUES (N'MyDept', N'MyNewGroup');
UPDATE HumanResources.Department
SET GroupName = N'Resource Control'
WHERE GroupName = N'Inventory Management';
DELETE FROM HumanResources.Department
WHERE Name = N'MyDept';
-- Obtain the end of the time interval.
SET @end_time = GETDATE();
-- Map the time interval to a change data capture query range.
SET @from_lsn = sys.fn_cdc_map_time_to_lsn('smallest greater than or equal', @begin_time);
SET @from_lsn = ISNULL(sys.fn_cdc_map_time_to_lsn('smallest greater than or equal', @begin_time), [sys].[fn_cdc_get_min_lsn]('HR_Department') );
SET @to_lsn = sys.fn_cdc_map_time_to_lsn('largest less than or equal', @end_time);
-- Return the net changes occurring within the query window.
SELECT * FROM cdc.fn_cdc_get_net_changes_HR_Department(@from_lsn, @to_lsn, 'all');