SlideShare a Scribd company logo
1 of 19
About Change Tracking (SQL Server)
• What rows have changed for a user table?
• Only the fact that a row has changed is required, not how many times the
row has changed or the values of any intermediate changes.
• The latest data can be obtained directly from the table that is being tracked.
• Has a row changed?
• The fact that a row has changed and information about the change must be
available and recorded at the time that the change was made in the same
transaction.
Change tracking is a lightweight solution that provides an efficient change tracking mechanism
for applications. Typically, to enable applications to query for changes to data in a database and
access information that is related to the changes, application developers had to implement
custom change tracking mechanisms. Creating these mechanisms usually involved a lot of work
and frequently involved using a combination of triggers, timestamp columns, new tables to store
tracking information, and custom cleanup processes.
One-Way Synchronization Applications
Two-Way Synchronization Applications
ALTER PROCEDURE [dbo].[GETUPLOADSESSIONLOG]
@lastSyncVer BIGINT
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ
UNCOMMITTED
DECLAR@minCTVer =
CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID('UPLOADSES
SIONLOG'));
E @minCTVer BIGINT;
SELECT
IF (@lastSyncVer >= 0) AND (@lastSyncVer >= @minCTVer)
BEGIN
SELECT usl.[DATASTOREID], usl.[UPLOADSESSIONID],
usl.[STATUS], usl.[MESSAGE], usl.[DATECREATED]
FROM [dbo].[UPLOADSESSIONLOG] AS usl with(nolock)
INNER JOIN CHANGETABLE(CHANGES
[dbo].[UPLOADSESSIONLOG], @lastSyncVer) AS ct ON usl.[ID] =
ct.[ID]
END
ELSE
BEGIN
SELECT [DATASTOREID], [UPLOADSESSIONID], [STATUS],
[MESSAGE], [DATECREATED]
FROM [dbo].[UPLOADSESSIONLOG] with(nolock)
ALTER PROCEDURE [dbo].[GETUPLOADSESSION]
@jobID NVARCHAR(20),
@dataGroup BIGINT,
@lastSyncVer BIGINT
AS
BEGIN
---SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE @minCTVer BIGINT;
SELECT @minCTVer = CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID('UPLOADSESSION'));
IF (@lastSyncVer >= 0) AND (@lastSyncVer >= @minCTVer)
BEGIN
SELECT us.[DATASTOREID], us.[UPLOADSESSIONID], us.[UPLOADPATH], us.[STATUS], us.[DATEUPLOADED],
us.[DATECREATED], us.[CHECKSUM], us.[FILESIZE], us.[ID], us.[RERUNFOR]
FROM [dbo].[UPLOADSESSION] us with(nolock)
INNER JOIN CHANGETABLE(CHANGES [dbo].[UPLOADSESSION], @lastSyncVer) AS CT ON us.[ID] = CT.[ID]
INNER JOIN [dbo].[DATASTORE] ds with(nolock) ON us.[DATASTOREID] = ds.[ID]
INNER JOIN [dbo].[DATAGROUP] dg with(nolock) ON ds.[DATAGROUPID] = dg.[ID]
WHERE dg.[ID] = @dataGroup
AND us.[JOBID] = @jobID
AND us.[RERUN] = 0
ORDER BY us.[ID]
END
ELSE
• Change Tracking Cleanup
• Track Data Changes (SQL Server)
• Benefits of Using Change Data Capture or Change Tracking
• Feature Differences Between Change Data Capture and Change
Tracking
Job 1:
Firstly, to enable tracking on a table, the tracking should be enabled at two levels:
1- The whole database
2- On each table that the user wishes to track.
…
server static void aaChangeTracking_1_EnableTracking(Args _args)
{
Query query;
AifChangeTracking changeTracking;
AifChangeTrackingTable ctTable;
;
//Need to be run on server side
new AifChangeTrackingPermission().assert();
info(strFmt("%1", AifChangeTrackingConfiguration::isChangeTrackingEnabled()));
// Run this first to globally enable changeTracking
//This should be run once
AifChangeTrackingConfiguration::enableChangeTracking(true);
// Here we are loading the query that the webservice uses (I took a wild guess to figure this out)
query = new Query("AxdItem");
AifChangeTrackingConfiguration::enableChangeTrackingForQuery("TestScope1", query);
changeTracking = AifChangeTracking::construct(query, "TestScope1", AifChangeTrackingType::SqlChangeTracking);
// Did we enable change tracking?
info(changeTracking.isChangeTrackingEnabled()? "true" : "false");
// did we enable change tracking for this specific query?
info(changeTracking.isChangeTrackingEnabledForQuery()? "q:true" : "q:false");
// redundant check... but anyways its checking if the specific table has change tracking enabled
info(changeTracking.isChangeTrackingEnabledForTable(tableNum(InventTable))? "t:true" : "t:false");
// Revert the permission assert
CodeAccessPermission::revertAssert();
}
• Job 2:
• After enabling the tracking in both the database and the tables that
we need to track, we need to link the child tables to the parent table.
This means that if a change occurred (insert or update) in the child
table then the parent table should be touched.
•
server static void aaChangeTracking_2_CreateTriggers(Args _args)
{
Query query;
AifChangeTrackingTable ctTable;
;
//Need to be run on server side
new AifChangeTrackingPermission().assert();
query = new Query("AxdItem");
AifChangeTrackingConfiguration::createTouchTriggersForQuery("TestScope1",
AifChangeTrackingTriggerType::AfterInsert, query);
AifChangeTrackingConfiguration::createTouchTriggersForQuery("TestScope1",
AifChangeTrackingTriggerType::AfterUpdate, query);
// Revert the permission assert
CodeAccessPermission::revertAssert();
}
• Job 3:
• Tracking the versions will be saved in a table in AX called
AifSQLCTVersion. The following code will update this version control
table:
•
static void aaChangeTracking_3_UpdateTrackingVersion(Args _args)
{
container conVersion;
;
//To record the newest version
//There is a standard AX batch job that does this
AifSqlCtChangeTracking::recordCurrentVersion();
}
• This can be run as a batch job by calling the following batch job:
AifChangeTrackingVersionUpdateJob
•
• Job 4:
• To find the changes, I created a batch job that will define a query for
the inventTable only. Remember in job 2 we created triggers for the
child tables to touch the inventTable. So, in this case we don’t need to
check the changes in the child tables (e.g. invnetTableModule). we only
need to call the inventTable.
•
server static void aaChangeTracking_4_GetChangedTable(Args _args)
{
Query _query;
QueryBuildDataSource _qbds;
AifChangeTracking _changeTracking;
utcDateTime _dateTimeYesterday;
AifChangeTrackingTable ctTable;
;
//Change the date based on what is needed
_dateTimeYesterday = DateTimeUtil::addDays(DateTimeUtil::getSystemDateTime(), -2);
new AifChangeTrackingPermission().assert();
_query = new Query();
_qbds = _query.addDataSource(tableNum(InventTable));
_changeTracking = AifChangeTracking::construct(_query);
_changeTracking.getChanges(_dateTimeYesterday, ctTable);
while select ctTable
{
info(strFmt("%1", ctTable.KeyField_RecId));
}
CodeAccessPermission::revertAssert();
}
Opening RPF Files
• In Dynamics AX 2012, we have this concept of pushing and pulling the
data for Retail between Head Office and Store.
• The data is written in XML form, compressed into an rpf file then
saved to a working folder. These rpf files or data packages can be
opened using DDPackView.exe which is available if you install Async
Server (Head Office) or Async Client (Store).
You may find it in:
• C:Program Files (x86)Microsoft Dynamics AX60CDXAsync
ServerPackage
If you execute it from here, you will need to specify the actual rpf file you want to check and
click Convert. You might encounter an error:
Could not load file or assembly 'Microsoft.Dynamics.Retail.StoreConnect.RequestHandlerManager,
Version=6.3.0.0, Cuture=neutral, PublicKeyToken=xxxx or one of its dependencies. The system
cannot find the file specified.
Usually, I just copy the following in the same folder of DDPackView:
DDPackView.exe.config
• Microsoft.Dynamics.Retail.EventTraceProvider.dll
• Microsoft.Dynamics.Retail.StoreConnect.Request.Compression.dll
• Microsoft.Dynamics.Retail.StoreConnect.Request.Interface.dll
• Microsoft.Dynamics.Retail.StoreConnect.Request.RequestHandlerManager.d
ll
And the RequestHandlers folder which contains:
• Microsoft.Dynamics.Retail.StoreConnect.Request.Base.dll
• Microsoft.Dynamics.Retail.StoreConnect.Request.SQLHandler.dll
You may find all of these from the CDXAsync ClientPackage folder.
I usually have a handy copy of these because it's just easier that way,
Anyway, if you're successful with the conversion
you should be able to see something like this:
This is an RPF file of a full sync 1000-Currency job. So if you are going to check the
Scheduler job for 1000, every subjobs here has its corresponding xml file:
Thank You

More Related Content

What's hot

Accessing data with android cursors
Accessing data with android cursorsAccessing data with android cursors
Accessing data with android cursorsinfo_zybotech
 
Spring data ii
Spring data iiSpring data ii
Spring data ii명철 강
 
Wicket Security Presentation
Wicket Security PresentationWicket Security Presentation
Wicket Security Presentationmrmean
 
SSMS-waitstats
SSMS-waitstatsSSMS-waitstats
SSMS-waitstatsE Blake
 
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Ryosuke Uchitate
 
Create & Execute First Hadoop MapReduce Project in.pptx
Create & Execute First Hadoop MapReduce Project in.pptxCreate & Execute First Hadoop MapReduce Project in.pptx
Create & Execute First Hadoop MapReduce Project in.pptxvishal choudhary
 
Creating a physical standby database 11g on windows
Creating a physical standby database 11g on windowsCreating a physical standby database 11g on windows
Creating a physical standby database 11g on windowsRoo Wall
 
Multiple Flat Files(CSV) to Target Table in ODI12c(12.2.1.0.0)
Multiple Flat Files(CSV) to Target Table in ODI12c(12.2.1.0.0)Multiple Flat Files(CSV) to Target Table in ODI12c(12.2.1.0.0)
Multiple Flat Files(CSV) to Target Table in ODI12c(12.2.1.0.0)Darshankumar Prajapati
 
ODI 11g - Multiple Flat Files to Oracle DB Table by taking File Name dynamica...
ODI 11g - Multiple Flat Files to Oracle DB Table by taking File Name dynamica...ODI 11g - Multiple Flat Files to Oracle DB Table by taking File Name dynamica...
ODI 11g - Multiple Flat Files to Oracle DB Table by taking File Name dynamica...Darshankumar Prajapati
 
Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門Ryosuke Uchitate
 
Cloning Oracle EBS R12: A Step by Step Procedure
Cloning Oracle EBS R12: A Step by Step ProcedureCloning Oracle EBS R12: A Step by Step Procedure
Cloning Oracle EBS R12: A Step by Step ProcedureOrazer Technologies
 
Table partitioning in PostgreSQL + Rails
Table partitioning in PostgreSQL + RailsTable partitioning in PostgreSQL + Rails
Table partitioning in PostgreSQL + RailsAgnieszka Figiel
 
Managing Oracle Streams Using Enterprise Manager Grid Control
Managing Oracle Streams Using Enterprise Manager Grid ControlManaging Oracle Streams Using Enterprise Manager Grid Control
Managing Oracle Streams Using Enterprise Manager Grid Controlscottb411
 
Durable functions
Durable functionsDurable functions
Durable functions명신 김
 
Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017
Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017
Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017Mike Nakhimovich
 
Vs2010and Ne Tframework
Vs2010and Ne TframeworkVs2010and Ne Tframework
Vs2010and Ne TframeworkKulveerSingh
 
Stored procedure Notes By Durgesh Singh
Stored procedure Notes By Durgesh SinghStored procedure Notes By Durgesh Singh
Stored procedure Notes By Durgesh Singhimdurgesh
 
Importance Of Sa P2
Importance Of Sa P2Importance Of Sa P2
Importance Of Sa P2moosty
 

What's hot (20)

Accessing data with android cursors
Accessing data with android cursorsAccessing data with android cursors
Accessing data with android cursors
 
Spring data ii
Spring data iiSpring data ii
Spring data ii
 
Android - Saving data
Android - Saving dataAndroid - Saving data
Android - Saving data
 
Wicket Security Presentation
Wicket Security PresentationWicket Security Presentation
Wicket Security Presentation
 
SSMS-waitstats
SSMS-waitstatsSSMS-waitstats
SSMS-waitstats
 
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!Amazon Cognito使って認証したい?それならSpring Security使いましょう!
Amazon Cognito使って認証したい?それならSpring Security使いましょう!
 
Backendless apps
Backendless appsBackendless apps
Backendless apps
 
Create & Execute First Hadoop MapReduce Project in.pptx
Create & Execute First Hadoop MapReduce Project in.pptxCreate & Execute First Hadoop MapReduce Project in.pptx
Create & Execute First Hadoop MapReduce Project in.pptx
 
Creating a physical standby database 11g on windows
Creating a physical standby database 11g on windowsCreating a physical standby database 11g on windows
Creating a physical standby database 11g on windows
 
Multiple Flat Files(CSV) to Target Table in ODI12c(12.2.1.0.0)
Multiple Flat Files(CSV) to Target Table in ODI12c(12.2.1.0.0)Multiple Flat Files(CSV) to Target Table in ODI12c(12.2.1.0.0)
Multiple Flat Files(CSV) to Target Table in ODI12c(12.2.1.0.0)
 
ODI 11g - Multiple Flat Files to Oracle DB Table by taking File Name dynamica...
ODI 11g - Multiple Flat Files to Oracle DB Table by taking File Name dynamica...ODI 11g - Multiple Flat Files to Oracle DB Table by taking File Name dynamica...
ODI 11g - Multiple Flat Files to Oracle DB Table by taking File Name dynamica...
 
Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門
 
Cloning Oracle EBS R12: A Step by Step Procedure
Cloning Oracle EBS R12: A Step by Step ProcedureCloning Oracle EBS R12: A Step by Step Procedure
Cloning Oracle EBS R12: A Step by Step Procedure
 
Table partitioning in PostgreSQL + Rails
Table partitioning in PostgreSQL + RailsTable partitioning in PostgreSQL + Rails
Table partitioning in PostgreSQL + Rails
 
Managing Oracle Streams Using Enterprise Manager Grid Control
Managing Oracle Streams Using Enterprise Manager Grid ControlManaging Oracle Streams Using Enterprise Manager Grid Control
Managing Oracle Streams Using Enterprise Manager Grid Control
 
Durable functions
Durable functionsDurable functions
Durable functions
 
Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017
Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017
Data Loading Made Easy with Mike Nakhimovich DroidCon Italy 2017
 
Vs2010and Ne Tframework
Vs2010and Ne TframeworkVs2010and Ne Tframework
Vs2010and Ne Tframework
 
Stored procedure Notes By Durgesh Singh
Stored procedure Notes By Durgesh SinghStored procedure Notes By Durgesh Singh
Stored procedure Notes By Durgesh Singh
 
Importance Of Sa P2
Importance Of Sa P2Importance Of Sa P2
Importance Of Sa P2
 

Similar to Change tracking

Sql storeprocedure
Sql storeprocedureSql storeprocedure
Sql storeprocedureftz 420
 
Advance Sql Server Store procedure Presentation
Advance Sql Server Store procedure PresentationAdvance Sql Server Store procedure Presentation
Advance Sql Server Store procedure PresentationAmin Uddin
 
Apache Calcite Tutorial - BOSS 21
Apache Calcite Tutorial - BOSS 21Apache Calcite Tutorial - BOSS 21
Apache Calcite Tutorial - BOSS 21Stamatis Zampetakis
 
How to perform debounce in react
How to perform debounce in reactHow to perform debounce in react
How to perform debounce in reactBOSC Tech Labs
 
Acutate - Using Stored Procedure
Acutate - Using Stored ProcedureAcutate - Using Stored Procedure
Acutate - Using Stored ProcedureAishwarya Savant
 
Autonomous Transaction Processing (ATP): In Heavy Traffic, Why Drive Stick?
Autonomous Transaction Processing (ATP): In Heavy Traffic, Why Drive Stick?Autonomous Transaction Processing (ATP): In Heavy Traffic, Why Drive Stick?
Autonomous Transaction Processing (ATP): In Heavy Traffic, Why Drive Stick?Jim Czuprynski
 
Oracle data capture c dc
Oracle data capture c dcOracle data capture c dc
Oracle data capture c dcAmit Sharma
 
Oracle - Program with PL/SQL - Lession 17
Oracle - Program with PL/SQL - Lession 17Oracle - Program with PL/SQL - Lession 17
Oracle - Program with PL/SQL - Lession 17Thuan Nguyen
 
Windows Mobile 5.0 Data Access And Storage Webcast
Windows Mobile 5.0 Data Access And Storage WebcastWindows Mobile 5.0 Data Access And Storage Webcast
Windows Mobile 5.0 Data Access And Storage WebcastVinod Kumar
 
Getting Started with MySQL II
Getting Started with MySQL IIGetting Started with MySQL II
Getting Started with MySQL IISankhya_Analytics
 
Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Joe Keeley
 
Murach : How to work with session state and cookies
Murach : How to work with session state and cookiesMurach : How to work with session state and cookies
Murach : How to work with session state and cookiesMahmoudOHassouna
 
Tony jambu (obscure) tools of the trade for tuning oracle sq ls
Tony jambu   (obscure) tools of the trade for tuning oracle sq lsTony jambu   (obscure) tools of the trade for tuning oracle sq ls
Tony jambu (obscure) tools of the trade for tuning oracle sq lsInSync Conference
 
PostgreSQL Performance Tables Partitioning vs. Aggregated Data Tables
PostgreSQL Performance Tables Partitioning vs. Aggregated Data TablesPostgreSQL Performance Tables Partitioning vs. Aggregated Data Tables
PostgreSQL Performance Tables Partitioning vs. Aggregated Data TablesSperasoft
 
Streamlining data analysis through environmental alerts how to integrate ambe...
Streamlining data analysis through environmental alerts how to integrate ambe...Streamlining data analysis through environmental alerts how to integrate ambe...
Streamlining data analysis through environmental alerts how to integrate ambe...Ambee
 
How to – data integrity checks in batch processing
How to – data integrity checks in batch processingHow to – data integrity checks in batch processing
How to – data integrity checks in batch processingSon Nguyen
 
performancetestingjmeter-121109061704-phpapp02
performancetestingjmeter-121109061704-phpapp02performancetestingjmeter-121109061704-phpapp02
performancetestingjmeter-121109061704-phpapp02Gopi Raghavendra
 
performancetestingjmeter-121109061704-phpapp02 (1)
performancetestingjmeter-121109061704-phpapp02 (1)performancetestingjmeter-121109061704-phpapp02 (1)
performancetestingjmeter-121109061704-phpapp02 (1)QA Programmer
 
Wcf data services
Wcf data servicesWcf data services
Wcf data servicesEyal Vardi
 
Salesforce Summer 14 Release
Salesforce Summer 14 ReleaseSalesforce Summer 14 Release
Salesforce Summer 14 ReleaseJyothylakshmy P.U
 

Similar to Change tracking (20)

Sql storeprocedure
Sql storeprocedureSql storeprocedure
Sql storeprocedure
 
Advance Sql Server Store procedure Presentation
Advance Sql Server Store procedure PresentationAdvance Sql Server Store procedure Presentation
Advance Sql Server Store procedure Presentation
 
Apache Calcite Tutorial - BOSS 21
Apache Calcite Tutorial - BOSS 21Apache Calcite Tutorial - BOSS 21
Apache Calcite Tutorial - BOSS 21
 
How to perform debounce in react
How to perform debounce in reactHow to perform debounce in react
How to perform debounce in react
 
Acutate - Using Stored Procedure
Acutate - Using Stored ProcedureAcutate - Using Stored Procedure
Acutate - Using Stored Procedure
 
Autonomous Transaction Processing (ATP): In Heavy Traffic, Why Drive Stick?
Autonomous Transaction Processing (ATP): In Heavy Traffic, Why Drive Stick?Autonomous Transaction Processing (ATP): In Heavy Traffic, Why Drive Stick?
Autonomous Transaction Processing (ATP): In Heavy Traffic, Why Drive Stick?
 
Oracle data capture c dc
Oracle data capture c dcOracle data capture c dc
Oracle data capture c dc
 
Oracle - Program with PL/SQL - Lession 17
Oracle - Program with PL/SQL - Lession 17Oracle - Program with PL/SQL - Lession 17
Oracle - Program with PL/SQL - Lession 17
 
Windows Mobile 5.0 Data Access And Storage Webcast
Windows Mobile 5.0 Data Access And Storage WebcastWindows Mobile 5.0 Data Access And Storage Webcast
Windows Mobile 5.0 Data Access And Storage Webcast
 
Getting Started with MySQL II
Getting Started with MySQL IIGetting Started with MySQL II
Getting Started with MySQL II
 
Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019
 
Murach : How to work with session state and cookies
Murach : How to work with session state and cookiesMurach : How to work with session state and cookies
Murach : How to work with session state and cookies
 
Tony jambu (obscure) tools of the trade for tuning oracle sq ls
Tony jambu   (obscure) tools of the trade for tuning oracle sq lsTony jambu   (obscure) tools of the trade for tuning oracle sq ls
Tony jambu (obscure) tools of the trade for tuning oracle sq ls
 
PostgreSQL Performance Tables Partitioning vs. Aggregated Data Tables
PostgreSQL Performance Tables Partitioning vs. Aggregated Data TablesPostgreSQL Performance Tables Partitioning vs. Aggregated Data Tables
PostgreSQL Performance Tables Partitioning vs. Aggregated Data Tables
 
Streamlining data analysis through environmental alerts how to integrate ambe...
Streamlining data analysis through environmental alerts how to integrate ambe...Streamlining data analysis through environmental alerts how to integrate ambe...
Streamlining data analysis through environmental alerts how to integrate ambe...
 
How to – data integrity checks in batch processing
How to – data integrity checks in batch processingHow to – data integrity checks in batch processing
How to – data integrity checks in batch processing
 
performancetestingjmeter-121109061704-phpapp02
performancetestingjmeter-121109061704-phpapp02performancetestingjmeter-121109061704-phpapp02
performancetestingjmeter-121109061704-phpapp02
 
performancetestingjmeter-121109061704-phpapp02 (1)
performancetestingjmeter-121109061704-phpapp02 (1)performancetestingjmeter-121109061704-phpapp02 (1)
performancetestingjmeter-121109061704-phpapp02 (1)
 
Wcf data services
Wcf data servicesWcf data services
Wcf data services
 
Salesforce Summer 14 Release
Salesforce Summer 14 ReleaseSalesforce Summer 14 Release
Salesforce Summer 14 Release
 

Change tracking

  • 1. About Change Tracking (SQL Server) • What rows have changed for a user table? • Only the fact that a row has changed is required, not how many times the row has changed or the values of any intermediate changes. • The latest data can be obtained directly from the table that is being tracked. • Has a row changed? • The fact that a row has changed and information about the change must be available and recorded at the time that the change was made in the same transaction. Change tracking is a lightweight solution that provides an efficient change tracking mechanism for applications. Typically, to enable applications to query for changes to data in a database and access information that is related to the changes, application developers had to implement custom change tracking mechanisms. Creating these mechanisms usually involved a lot of work and frequently involved using a combination of triggers, timestamp columns, new tables to store tracking information, and custom cleanup processes.
  • 2.
  • 3. One-Way Synchronization Applications Two-Way Synchronization Applications
  • 4. ALTER PROCEDURE [dbo].[GETUPLOADSESSIONLOG] @lastSyncVer BIGINT AS BEGIN SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED DECLAR@minCTVer = CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID('UPLOADSES SIONLOG')); E @minCTVer BIGINT; SELECT IF (@lastSyncVer >= 0) AND (@lastSyncVer >= @minCTVer) BEGIN SELECT usl.[DATASTOREID], usl.[UPLOADSESSIONID], usl.[STATUS], usl.[MESSAGE], usl.[DATECREATED] FROM [dbo].[UPLOADSESSIONLOG] AS usl with(nolock) INNER JOIN CHANGETABLE(CHANGES [dbo].[UPLOADSESSIONLOG], @lastSyncVer) AS ct ON usl.[ID] = ct.[ID] END ELSE BEGIN SELECT [DATASTOREID], [UPLOADSESSIONID], [STATUS], [MESSAGE], [DATECREATED] FROM [dbo].[UPLOADSESSIONLOG] with(nolock)
  • 5. ALTER PROCEDURE [dbo].[GETUPLOADSESSION] @jobID NVARCHAR(20), @dataGroup BIGINT, @lastSyncVer BIGINT AS BEGIN ---SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED DECLARE @minCTVer BIGINT; SELECT @minCTVer = CHANGE_TRACKING_MIN_VALID_VERSION(OBJECT_ID('UPLOADSESSION')); IF (@lastSyncVer >= 0) AND (@lastSyncVer >= @minCTVer) BEGIN SELECT us.[DATASTOREID], us.[UPLOADSESSIONID], us.[UPLOADPATH], us.[STATUS], us.[DATEUPLOADED], us.[DATECREATED], us.[CHECKSUM], us.[FILESIZE], us.[ID], us.[RERUNFOR] FROM [dbo].[UPLOADSESSION] us with(nolock) INNER JOIN CHANGETABLE(CHANGES [dbo].[UPLOADSESSION], @lastSyncVer) AS CT ON us.[ID] = CT.[ID] INNER JOIN [dbo].[DATASTORE] ds with(nolock) ON us.[DATASTOREID] = ds.[ID] INNER JOIN [dbo].[DATAGROUP] dg with(nolock) ON ds.[DATAGROUPID] = dg.[ID] WHERE dg.[ID] = @dataGroup AND us.[JOBID] = @jobID AND us.[RERUN] = 0 ORDER BY us.[ID] END ELSE
  • 6. • Change Tracking Cleanup • Track Data Changes (SQL Server) • Benefits of Using Change Data Capture or Change Tracking • Feature Differences Between Change Data Capture and Change Tracking
  • 7. Job 1: Firstly, to enable tracking on a table, the tracking should be enabled at two levels: 1- The whole database 2- On each table that the user wishes to track.
  • 8. … server static void aaChangeTracking_1_EnableTracking(Args _args) { Query query; AifChangeTracking changeTracking; AifChangeTrackingTable ctTable; ; //Need to be run on server side new AifChangeTrackingPermission().assert(); info(strFmt("%1", AifChangeTrackingConfiguration::isChangeTrackingEnabled())); // Run this first to globally enable changeTracking //This should be run once AifChangeTrackingConfiguration::enableChangeTracking(true); // Here we are loading the query that the webservice uses (I took a wild guess to figure this out) query = new Query("AxdItem"); AifChangeTrackingConfiguration::enableChangeTrackingForQuery("TestScope1", query); changeTracking = AifChangeTracking::construct(query, "TestScope1", AifChangeTrackingType::SqlChangeTracking); // Did we enable change tracking? info(changeTracking.isChangeTrackingEnabled()? "true" : "false"); // did we enable change tracking for this specific query? info(changeTracking.isChangeTrackingEnabledForQuery()? "q:true" : "q:false"); // redundant check... but anyways its checking if the specific table has change tracking enabled info(changeTracking.isChangeTrackingEnabledForTable(tableNum(InventTable))? "t:true" : "t:false"); // Revert the permission assert CodeAccessPermission::revertAssert(); }
  • 9. • Job 2: • After enabling the tracking in both the database and the tables that we need to track, we need to link the child tables to the parent table. This means that if a change occurred (insert or update) in the child table then the parent table should be touched. •
  • 10. server static void aaChangeTracking_2_CreateTriggers(Args _args) { Query query; AifChangeTrackingTable ctTable; ; //Need to be run on server side new AifChangeTrackingPermission().assert(); query = new Query("AxdItem"); AifChangeTrackingConfiguration::createTouchTriggersForQuery("TestScope1", AifChangeTrackingTriggerType::AfterInsert, query); AifChangeTrackingConfiguration::createTouchTriggersForQuery("TestScope1", AifChangeTrackingTriggerType::AfterUpdate, query); // Revert the permission assert CodeAccessPermission::revertAssert(); }
  • 11. • Job 3: • Tracking the versions will be saved in a table in AX called AifSQLCTVersion. The following code will update this version control table: •
  • 12. static void aaChangeTracking_3_UpdateTrackingVersion(Args _args) { container conVersion; ; //To record the newest version //There is a standard AX batch job that does this AifSqlCtChangeTracking::recordCurrentVersion(); } • This can be run as a batch job by calling the following batch job: AifChangeTrackingVersionUpdateJob •
  • 13. • Job 4: • To find the changes, I created a batch job that will define a query for the inventTable only. Remember in job 2 we created triggers for the child tables to touch the inventTable. So, in this case we don’t need to check the changes in the child tables (e.g. invnetTableModule). we only need to call the inventTable. •
  • 14. server static void aaChangeTracking_4_GetChangedTable(Args _args) { Query _query; QueryBuildDataSource _qbds; AifChangeTracking _changeTracking; utcDateTime _dateTimeYesterday; AifChangeTrackingTable ctTable; ; //Change the date based on what is needed _dateTimeYesterday = DateTimeUtil::addDays(DateTimeUtil::getSystemDateTime(), -2); new AifChangeTrackingPermission().assert(); _query = new Query(); _qbds = _query.addDataSource(tableNum(InventTable)); _changeTracking = AifChangeTracking::construct(_query); _changeTracking.getChanges(_dateTimeYesterday, ctTable); while select ctTable { info(strFmt("%1", ctTable.KeyField_RecId)); } CodeAccessPermission::revertAssert(); }
  • 15. Opening RPF Files • In Dynamics AX 2012, we have this concept of pushing and pulling the data for Retail between Head Office and Store. • The data is written in XML form, compressed into an rpf file then saved to a working folder. These rpf files or data packages can be opened using DDPackView.exe which is available if you install Async Server (Head Office) or Async Client (Store). You may find it in: • C:Program Files (x86)Microsoft Dynamics AX60CDXAsync ServerPackage
  • 16. If you execute it from here, you will need to specify the actual rpf file you want to check and click Convert. You might encounter an error: Could not load file or assembly 'Microsoft.Dynamics.Retail.StoreConnect.RequestHandlerManager, Version=6.3.0.0, Cuture=neutral, PublicKeyToken=xxxx or one of its dependencies. The system cannot find the file specified.
  • 17. Usually, I just copy the following in the same folder of DDPackView: DDPackView.exe.config • Microsoft.Dynamics.Retail.EventTraceProvider.dll • Microsoft.Dynamics.Retail.StoreConnect.Request.Compression.dll • Microsoft.Dynamics.Retail.StoreConnect.Request.Interface.dll • Microsoft.Dynamics.Retail.StoreConnect.Request.RequestHandlerManager.d ll And the RequestHandlers folder which contains: • Microsoft.Dynamics.Retail.StoreConnect.Request.Base.dll • Microsoft.Dynamics.Retail.StoreConnect.Request.SQLHandler.dll You may find all of these from the CDXAsync ClientPackage folder. I usually have a handy copy of these because it's just easier that way,
  • 18. Anyway, if you're successful with the conversion you should be able to see something like this: This is an RPF file of a full sync 1000-Currency job. So if you are going to check the Scheduler job for 1000, every subjobs here has its corresponding xml file: