Choosing between change event streaming, change data capture, change tracking, Azure Functions and Logic Apps to react to row changes.
From Ultra Transcenders DP-800 by Tony Rough (coming December 2026)
The right mechanism follows from three questions: does the consumer need old values or every intermediate change, must changes be pushed or can they be polled, and which platform hosts the database. Figure 12.1 turns the first two questions into a decision tree.
| Requirement | Best fit | Why not the alternative |
|---|---|---|
| Publish every row change to several downstream consumers in near real time | CES to Event Hubs or Fabric Eventstream | Polling options make each consumer query the database |
| Incremental ETL that needs before and after values or full history | CDC | Change tracking keeps no old values |
| Keep a cache or mobile client synchronised with current values, with conflict detection | Change tracking with CHANGETABLE |
CDC stores far more than needed |
| Run code on each change without hosting a poller | Azure Functions SQL trigger | A custom loop over CHANGETABLE is code to maintain |
| Start a low-code workflow (email, approvals, other SaaS connectors) on a new or changed row | Logic Apps SQL Server trigger | Functions needs code and deployment |
| Track changes in SQL database in Fabric | Change tracking (or CES, preview) | CDC isn’t supported |
| Capture deletes in a Logic Apps workflow | Built-in trigger in a Standard logic app | Managed triggers have no delete trigger |
Some combinations are blocked: CES can’t share a database with CDC or transactional replication, while change tracking coexists with both. Where an inline reaction inside the writing transaction is truly required, a T-SQL DML trigger (Chapter 3, “Programmability objects and error handling”) runs synchronously, but it adds its work, and any failure, to the user’s transaction; the mechanisms in this chapter keep that work out of the write path.
Common trap: Picking CES for a requirement to load a target with all existing rows plus future changes - CES never sends rows that existed before it was enabled, so an initial load has to be done separately.
This note is one section of Ultra Transcenders DP-800: Developing AI-Enabled Database Solutions, an independent study guide that explains every topic the exam covers by technology, with comparison tables, diagrams and the common traps, plus a glossary linked to Microsoft Learn.
Due on Amazon in December 2026, in Kindle and paperback editions.
About the book · DP-800 terms in the glossary · All DP-800 study notes
How each isolation level trades consistency for concurrency, when to use RCSI or snapshot isolation, and which anomalies each one prevents.
How Always Encrypted keeps keys away from the database engine, deterministic versus randomised encryption, and secure enclaves.
How to build row-level security with an inline predicate function and a security policy, and how filter and block predicates differ.
How the OVER clause partitions, orders and frames rows, and how ROWS and RANGE frames decide which rows each calculation sees.
How temporal tables keep row history automatically, and how FOR SYSTEM_TIME AS OF, BETWEEN and ALL query it.
When exact k-nearest-neighbour search is enough, when an approximate DiskANN vector index pays off, and why its metric must match the query.
How to combine full-text and vector search results with reciprocal rank fusion in T-SQL, and why RRF uses ranks rather than raw scores.