Category: Databases

Interpret the security impact of using AI-assisted tools (DP-800 Exam Prep)

This post is a part of the DP-800: Developing AI-Enabled Database Solutions Exam Prep Hub.
This topic falls under these sections:
Design and develop database solutions (35–40%)
   --> Design and implement SQL solutions by using AI-assisted tools
      --> Interpret security impact of using AI-assisted tools


Note that there are 10 practice questions (with answers) at the end of each section to help you solidify your knowledge of the material. Also, there are 4 practice tests with 30 questions each available from the hub's main page below the exam topics section.

Introduction

Unlike many traditional SQL development topics, this objective focuses less on writing T-SQL and more on understanding how AI coding assistants affect security, privacy, compliance, and governance throughout the software development lifecycle.

For the DP-800 exam, you should understand:

  • Security risks associated with AI coding assistants
  • Responsible use of AI-generated code
  • Protection of confidential data
  • Compliance considerations
  • Secure prompt engineering
  • Human review requirements
  • Organizational governance for AI-assisted development
  • Microsoft AI tooling security capabilities

Why Security Matters When Using AI-Assisted Tools

Modern AI assistants such as:

  • Microsoft Copilot
  • GitHub Copilot
  • Azure AI Foundry
  • Microsoft Fabric Copilot
  • SQL Database Copilot experiences
  • Azure Data Studio AI extensions
  • Visual Studio AI-assisted development

can dramatically improve developer productivity.

However, they also introduce new risks.

AI systems often process:

  • prompts
  • source code
  • database schema
  • stored procedures
  • configuration files
  • API definitions
  • infrastructure code
  • documentation

If developers expose sensitive information to an AI system, that information could violate organizational security policies.

Therefore:

AI should improve developer productivity—not weaken database security.


Primary Security Risks

The exam expects candidates to recognize several categories of risk.

1. Exposure of Sensitive Information

Never include confidential information inside prompts.

Examples include:

  • passwords
  • connection strings
  • API keys
  • access tokens
  • customer data
  • Personally Identifiable Information (PII)
  • Protected Health Information (PHI)
  • financial records
  • encryption keys

Bad example:

“Optimize this stored procedure that accesses CustomerCreditCards.”

Better:

Replace confidential objects with generic examples.

CustomerTable
OrderTable
SalesTable

instead of production names.


2. Leakage of Intellectual Property

Many organizations consider:

  • SQL code
  • stored procedures
  • business rules
  • AI models
  • algorithms
  • database architecture

to be proprietary.

Developers should avoid submitting confidential business logic into public AI services unless organizational policy permits it.


3. AI Hallucinations

AI-generated code may:

  • invent SQL syntax
  • generate nonexistent functions
  • misuse permissions
  • recommend deprecated features
  • introduce vulnerabilities

Example:

AI may suggest:

GRANT CONTROL TO PUBLIC

This is almost never appropriate.

Always validate AI-generated SQL.


4. Insecure Code Generation

AI sometimes generates code that:

  • lacks input validation
  • uses dynamic SQL unsafely
  • ignores least privilege
  • omits error handling
  • exposes excessive permissions

Example:

Unsafe:

SET @sql =
'SELECT * FROM Orders WHERE CustomerID=' + @CustomerID
EXEC(@sql)

Preferred:

sp_executesql

with parameters.


5. Compliance Violations

Many industries have regulations governing data usage.

Examples:

  • GDPR
  • HIPAA
  • PCI DSS
  • ISO 27001
  • SOC 2

Uploading regulated information into unauthorized AI services may violate compliance requirements.


Human Review is Required

One of the most important DP-800 concepts:

AI assists developers—it does not replace secure code review.

Every AI-generated recommendation should be reviewed for:

  • correctness
  • performance
  • security
  • compliance
  • maintainability

Human approval remains essential.


Secure Prompt Engineering

Prompt engineering also has security implications.

Good prompts avoid exposing sensitive information.

Instead of:

“Here’s our production database schema.”

Use:

“Here’s a simplified example schema.”

Good prompts:

  • remove customer data
  • remove passwords
  • remove secrets
  • anonymize identifiers
  • generalize business logic

Protecting Secrets

Never place secrets into AI prompts.

Examples include:

  • Azure SQL passwords
  • Azure Storage keys
  • SAS tokens
  • API keys
  • OAuth tokens
  • certificates
  • encryption keys

Instead:

<ConnectionString>

or

<MyAPIKey>

as placeholders.


Protect Customer Data

Sensitive customer information includes:

  • names
  • addresses
  • SSNs
  • passport numbers
  • emails
  • phone numbers
  • medical records
  • payment information

Instead of:

John Smith

Use:

Customer A

Instead of:

4111-1111-1111-1111

Use:

<CardNumber>

AI and Least Privilege

Generated SQL should follow the Principle of Least Privilege.

Avoid:

GRANT CONTROL

Prefer:

GRANT SELECT

or

GRANT EXECUTE

only when necessary.

AI suggestions should always be reviewed for excessive permissions.


Verify AI-Generated Security Recommendations

AI may recommend:

  • indexes
  • permissions
  • encryption
  • authentication methods
  • firewall rules

Always verify recommendations against:

  • Microsoft documentation
  • organizational standards
  • security policies
  • current SQL Server capabilities

Secure Development Lifecycle (SDL)

AI should support—not bypass—the Secure Development Lifecycle.

Typical workflow:

  1. Developer writes prompt
  2. AI generates code
  3. Developer reviews
  4. Static code analysis
  5. Security scanning
  6. Peer review
  7. Testing
  8. Deployment

AI does not eliminate security reviews.


AI-Generated SQL Must Still Be Tested

Always test:

  • SQL injection protection
  • permissions
  • transactions
  • rollback behavior
  • concurrency
  • performance
  • indexing
  • execution plans

Never deploy AI-generated code without testing.


Microsoft Copilot Security

Microsoft enterprise AI offerings provide important security capabilities.

Examples include:

  • enterprise authentication
  • Microsoft Entra ID integration
  • tenant isolation
  • role-based access control
  • compliance features
  • auditing
  • encryption
  • responsible AI safeguards

Organizations should understand which AI services are approved for handling sensitive information.


Governance of AI Usage

Organizations should establish governance policies that define:

  • approved AI tools
  • acceptable prompts
  • prohibited data types
  • review requirements
  • logging
  • auditing
  • approval workflows
  • compliance responsibilities

Developers should follow organizational AI usage policies.


Common Security Best Practices

When using AI-assisted SQL development:

  • Never share passwords or secrets.
  • Remove customer information from prompts.
  • Anonymize production schemas when possible.
  • Validate every AI-generated query.
  • Review permissions carefully.
  • Use parameterized queries instead of string concatenation.
  • Test AI-generated code before deployment.
  • Perform peer reviews.
  • Follow organizational governance policies.
  • Verify AI recommendations against Microsoft documentation.

Exam Tips

Know the differences between:

ConceptKey Point
AI AssistanceImproves productivity but requires review
Human ReviewAlways required before deployment
Sensitive DataNever include in prompts
ComplianceAI usage must satisfy organizational regulations
SecretsNever expose passwords, keys, or tokens
Least PrivilegeAI-generated permissions should be minimal
GovernanceOrganizations define approved AI usage
Responsible AIAI outputs must be validated for security and correctness

DP-800 Exam Tips

Expect scenario-based questions such as:

  • Is this prompt safe?
  • Which information should be removed before using Copilot?
  • Which AI recommendation should be rejected?
  • Which code introduces SQL injection?
  • Which permission follows least privilege?
  • How should confidential schemas be shared?
  • What review is still required after AI generates code?
  • Which compliance issue exists?
  • Which AI-generated recommendation is safest?
  • Which governance practice should be followed?

The correct answer almost always favors:

  • protecting sensitive information,
  • minimizing permissions,
  • validating AI-generated code,
  • following organizational security policies, and
  • requiring human review before deployment.

Practice Exam Questions

Question 1

A developer wants to use an AI coding assistant to optimize a stored procedure. Which information should NOT be included in the prompt?

A. Sample table names

B. Production connection string containing credentials

C. Database version

D. Execution plan summary

Correct Answer: B

Explanation:
Connection strings containing usernames, passwords, or other credentials are sensitive secrets and should never be shared with AI tools. Replace them with placeholders before submitting prompts.


Question 2

Which security principle should always be applied when reviewing AI-generated SQL permissions?

A. Full administrative access

B. Principle of Least Privilege

C. Maximum compatibility

D. Public access

Correct Answer: B

Explanation:
AI-generated code should grant only the permissions necessary to perform the required task. Avoid overly broad permissions such as CONTROL or db_owner unless absolutely required.


Question 3

An AI assistant generates a stored procedure that concatenates user input into a SQL statement. What should the developer do?

A. Deploy it because AI generated it

B. Ignore it

C. Replace it with parameterized SQL

D. Disable indexing

Correct Answer: C

Explanation:
Dynamic SQL created through string concatenation is vulnerable to SQL injection. Use parameterized queries or sp_executesql to safely pass user input.


Question 4

A company must comply with GDPR. Which prompt represents the safest practice?

A. Replace customer information with anonymized sample data

B. Include production payment records

C. Upload an entire production database backup

D. Include customer names and addresses

Correct Answer: A

Explanation:
Personally identifiable information should be removed or anonymized before using AI-assisted development tools to reduce compliance and privacy risks.


Question 5

Why should developers review AI-generated SQL before deploying it?

A. AI-generated code is always optimized

B. AI may generate incorrect or insecure code

C. AI always follows organizational standards

D. AI automatically performs penetration testing

Correct Answer: B

Explanation:
AI-generated code can contain logical errors, security vulnerabilities, deprecated syntax, or poor performance choices. Human review remains essential.


Question 6

Which item is generally appropriate to include in an AI prompt?

A. Encryption keys

B. Customer Social Security numbers

C. Generic sample schema with fictional table names

D. Production API tokens

Correct Answer: C

Explanation:
Generic schemas without confidential business information allow AI to provide useful assistance while protecting sensitive organizational data.


Question 7

Which activity remains part of the Secure Development Lifecycle even when AI generates most of the SQL code?

A. Eliminating peer review

B. Skipping security testing

C. Removing code reviews

D. Performing security validation and testing

Correct Answer: D

Explanation:
AI accelerates development but does not replace testing, peer reviews, static analysis, or security validation.


Question 8

What is the primary purpose of organizational AI governance policies?

A. Increase CPU utilization

B. Define approved and secure use of AI tools

C. Eliminate documentation

D. Replace database administrators

Correct Answer: B

Explanation:
Governance policies establish which AI tools are approved, what data may be shared, required review processes, auditing requirements, and compliance expectations.


Question 9

An AI assistant recommends granting CONTROL permissions to simplify application development. What should the developer do first?

A. Apply the recommendation immediately

B. Replace CONTROL with db_owner

C. Review whether a lower permission satisfies the requirement

D. Disable authentication

Correct Answer: C

Explanation:
Broad permissions should be carefully reviewed. Following the Principle of Least Privilege helps reduce security risks by granting only the minimum required permissions.


Question 10

Which statement best describes responsible use of AI-assisted database development?

A. AI-generated code is production-ready without review.

B. AI eliminates the need for security testing.

C. AI guarantees compliance with regulations.

D. AI improves productivity, but developers remain responsible for validating security, correctness, and compliance.

Correct Answer: D

Explanation:
AI is a productivity tool, not an autonomous developer. Developers remain accountable for verifying code quality, security, regulatory compliance, and organizational standards before deployment.


Go to the DP-800 Exam Prep Hub main page

Write graph queries that use the MATCH operator (DP-800 Exam Prep)

This post is a part of the DP-800: Developing AI-Enabled Database Solutions Exam Prep Hub.
This topic falls under these sections:
Design and develop database solutions (35–40%)
   --> Write advanced T-SQL code
      --> Write graph queries that use the MATCH operator


Note that there are 10 practice questions (with answers) at the end of each section to help you solidify your knowledge of the material. Also, there are 4 practice tests with 30 questions each available from the hub's main page below the exam topics section.

Introduction

Many business problems involve relationships between entities rather than simple rows and columns. Examples include social networks, organizational hierarchies, fraud detection, recommendation engines, transportation networks, supply chains, and knowledge graphs. While relational databases excel at storing structured data, querying complex relationships often requires multiple self-joins that become increasingly difficult to write and maintain.

To address these scenarios, SQL Server and Azure SQL Database support graph databases through node tables, edge tables, and the MATCH operator. These capabilities allow developers to model and query relationships using graph patterns while continuing to leverage the relational database engine.

For the DP-800: Developing AI-Enabled Database Solutions certification exam, you should understand how to create graph objects and write graph queries using the MATCH operator.


What Is a Graph Database?

A graph database represents information as:

  • Nodes – entities or objects
  • Edges – relationships between entities

Instead of focusing solely on tables and foreign keys, graph databases emphasize how data is connected.

Example:

Alice ---- WorksWith ---- Bob
|
LivesIn
|
Orlando

In this example:

  • Alice, Bob, and Orlando are nodes
  • WorksWith and LivesIn are edges

Graph Database Components

SQL Server graph databases consist of two primary object types:

ObjectPurpose
Node TableStores entities
Edge TableStores relationships

Node Tables

Node tables represent entities.

Examples include:

  • Employees
  • Customers
  • Products
  • Cities
  • Departments
  • Suppliers

Example:

CREATE TABLE Person
(
PersonID INT PRIMARY KEY,
FullName NVARCHAR(100)
)
AS NODE;

The AS NODE clause creates a graph node table.


Edge Tables

Edge tables represent relationships between nodes.

Example:

CREATE TABLE WorksWith
(
SinceDate DATE
)
AS EDGE;

This table stores the relationship between two Person nodes.

SQL Server automatically maintains hidden graph metadata for node and edge tables.


Node and Edge Relationships

Suppose the following data exists:

John ---- WorksWith ---- Mary
Mary ---- WorksWith ---- Susan
John ---- Manages ---- David

Each person exists once in the node table.

Relationships exist separately in edge tables.


Why Use Graph Queries?

Traditional relational queries require joins.

Example:

Employee
Manager
Department

This often becomes:

Employee
JOIN Manager
JOIN Department
JOIN Office
JOIN Region

Graph queries simplify relationship traversal.


The MATCH Operator

The MATCH operator is the primary mechanism for querying graph relationships.

Instead of writing multiple joins, developers specify graph patterns.

General syntax:

SELECT ...
FROM ...
WHERE MATCH(pattern);

The pattern describes how nodes are connected.


Basic MATCH Query

Suppose the database contains:

Persons

  • John
  • Mary
  • Susan

Relationship

John → WorksWith → Mary

Query:

SELECT
p1.FullName,
p2.FullName
FROM Person p1,
WorksWith w,
Person p2
WHERE MATCH
(
p1-(w)->p2
);

Result:

FullNameFullName
JohnMary

Understanding Graph Pattern Syntax

Example:

p1-(w)->p2

Meaning:

  • Start with node p1
  • Traverse edge w
  • Reach node p2

Arrow direction matters.


Reverse Direction

Example:

p1<-(w)-p2

Meaning:

p2 → p1

The relationship is traversed in the opposite direction.


Multiple Relationships

Suppose:

John → Mary
Mary → Susan

Query:

WHERE MATCH
(
John-(WorksWith)->Mary-(WorksWith)->Susan
);

The MATCH operator follows multiple hops.


Multi-Hop Queries

Graph databases excel at traversing multiple relationships.

Example:

Find employees connected through two working relationships.

Employee
WorksWith
Employee
WorksWith
Employee

Without graphs this may require several joins.

With MATCH the relationship path is much easier to express.


Multiple Edge Types

Suppose the graph contains:

John
WorksWith
Mary
LivesIn
Seattle

Query:

John-(WorksWith)->Mary-(LivesIn)->Seattle

The MATCH operator supports multiple relationship types within a single query.


Using MATCH with SELECT

Example:

SELECT
p.FullName,
c.CityName
FROM Person p,
LivesIn l,
City c
WHERE MATCH
(
p-(l)->c
);

Result

PersonCity
JohnSeattle
MaryOrlando

Combining MATCH with WHERE

Additional filtering can be applied.

Example:

SELECT
p.FullName
FROM Person p,
WorksWith w,
Person p2
WHERE MATCH
(
p-(w)->p2
)
AND p2.Department='Sales';

Graph traversal occurs first.

The remaining rows are filtered normally.


MATCH and JOINs

Graph queries can still use relational joins.

Example:

SELECT
p.FullName,
d.DepartmentName
FROM Person p,
WorksWith w,
Person p2
JOIN Department d
ON p2.DepartmentID=d.DepartmentID
WHERE MATCH
(
p-(w)->p2
);

Graph features integrate with standard SQL.


Graph Queries for AI Applications

Graph databases are becoming increasingly valuable for AI applications because they naturally represent relationships between people, documents, products, concepts, and events.

Examples include:

  • Knowledge graphs
  • Recommendation systems
  • Fraud detection
  • Supply chain analysis
  • Social networks
  • Customer relationship analysis
  • Semantic search
  • Retrieval-Augmented Generation (RAG)
  • Entity linking
  • Relationship discovery

Large Language Models (LLMs) often benefit from graph data because relationships provide richer context than isolated rows.


Knowledge Graph Example

Suppose an AI application stores:

Customer
Purchased
Product
ManufacturedBy
Company

The MATCH operator can quickly discover:

  • Which products customers purchased
  • Which companies manufacture them
  • Similar purchasing relationships
  • Connected entities

Fraud Detection

Graph databases are excellent for identifying suspicious relationships.

Example:

Customer
Owns
Account
TransfersMoneyTo
Account
OwnedBy
Customer

MATCH queries can identify complex money-transfer networks that would require many joins in a traditional relational model.


Recommendation Engines

Streaming services often recommend content based on relationships.

Example:

User
Likes
Movie
DirectedBy
Director

Graph queries efficiently discover similar users and related content.


Relationship Discovery

Graph databases make it easy to answer questions such as:

  • Who works with whom?
  • Which customers purchased similar products?
  • Which suppliers serve the same regions?
  • Which employees report to the same manager?
  • Which products share common components?

These scenarios are ideal for MATCH queries.


Performance Considerations

Graph queries can outperform complex self-joins when relationship traversal is the primary objective.

Best practices include:

  • Keep node and edge tables appropriately indexed.
  • Filter data before traversing large graphs when possible.
  • Avoid unnecessary relationship hops.
  • Use graph queries only when relationships are central to the problem.
  • Continue using relational tables for highly tabular data.

Best Practices

  • Model entities as node tables.
  • Model relationships as edge tables.
  • Use descriptive edge names.
  • Keep graph models simple.
  • Combine MATCH with relational filtering when appropriate.
  • Choose graph queries only when relationship traversal is required.
  • Avoid replacing relational designs unnecessarily.
  • Document graph relationships clearly.
  • Test graph queries with realistic datasets.
  • Consider graph databases for AI-powered relationship analysis.

Common Exam Tips

For the DP-800 exam, remember the following:

  • Graph databases store entities as nodes and relationships as edges.
  • Node tables are created using AS NODE.
  • Edge tables are created using AS EDGE.
  • The MATCH operator traverses graph relationships.
  • Arrow direction (-> and <-) determines relationship direction.
  • MATCH can traverse multiple relationships in a single query.
  • Graph queries integrate with standard SQL statements.
  • Graph databases are well suited for knowledge graphs, recommendation engines, fraud detection, supply chains, and AI-enabled applications that rely on relationship analysis.

Practice Exam Questions

Question 1

Which SQL Server object stores relationships between entities in a graph database?

A. View

B. Node table

C. Edge table

D. Stored procedure

Answer: C

Explanation: Edge tables store the relationships between nodes and are created using the AS EDGE clause.


Question 2

Which clause is used when creating a graph node table?

A.

AS GRAPH

B.

AS NODE

C.

AS ENTITY

D.

AS OBJECT

Answer: B

Explanation: A graph node table is created by appending the AS NODE clause to a CREATE TABLE statement.


Question 3

What is the primary purpose of the MATCH operator?

A. Perform full-text searches

B. Compare two strings

C. Traverse graph relationships between nodes

D. Create graph indexes

Answer: C

Explanation: MATCH specifies graph traversal patterns, allowing SQL Server to navigate relationships represented by edge tables.


Question 4

In the graph pattern:

p1-(w)->p2

what does the arrow (->) indicate?

A. The relationship flows from p1 through edge w to p2.

B. The relationship flows from p2 to p1.

C. The query performs an inner join.

D. The graph contains duplicate nodes.

Answer: A

Explanation: The arrow indicates the direction of traversal from the starting node (p1) through the edge (w) to the destination node (p2).


Question 5

Which scenario is best suited for SQL Server graph queries?

A. Calculating monthly payroll totals

B. Traversing employee reporting relationships across multiple organizational levels

C. Sorting sales by date

D. Updating a single customer record

Answer: B

Explanation: Graph queries excel at traversing complex relationships, such as organizational hierarchies and reporting structures.


Question 6

Which statement about graph queries in SQL Server is true?

A. They cannot be combined with traditional SQL queries.

B. They require a separate graph database engine.

C. They can be combined with relational filtering and joins.

D. They replace foreign keys.

Answer: C

Explanation: SQL Server graph queries integrate with standard T-SQL and can be combined with joins, filters, and other relational features.


Question 7

Which of the following is represented by a node table?

A. A relationship between two customers

B. A connection between two products

C. A customer entity

D. A graph traversal path

Answer: C

Explanation: Node tables represent entities such as customers, employees, products, or cities, while edge tables represent the relationships between them.


Question 8

Why are graph databases valuable for Retrieval-Augmented Generation (RAG) and other AI solutions?

A. They automatically train language models.

B. They store only vector embeddings.

C. They eliminate the need for SQL queries.

D. They model and query rich relationships that provide additional context for AI systems.

Answer: D

Explanation: Graph databases capture connections among entities, allowing AI applications to retrieve contextual information that improves reasoning and search results.


Question 9

What is the advantage of using the MATCH operator instead of multiple self-joins?

A. It encrypts graph data automatically.

B. It simplifies expressing relationship traversal patterns.

C. It automatically creates indexes.

D. It eliminates the need for edge tables.

Answer: B

Explanation: MATCH provides a concise, intuitive syntax for traversing relationships that would otherwise require numerous joins.


Question 10

A database models employees, departments, and managers as graph nodes connected by edge tables. Which query feature should be used to find employees connected to a specific manager through defined relationships?

A. LIKE

B. GROUP BY

C. MERGE

D. MATCH

Answer: D

Explanation: The MATCH operator is specifically designed for traversing relationships in SQL Server graph databases and is the appropriate choice for this type of query.


Go to the DP-800 Exam Prep Hub main page

Write queries that include fuzzy string matching functions, such as EDIT_DISTANCE, EDIT_DISTANCE_SIMILARITY, and JARO_WINKLER_DISTANCE (DP-800 Exam Prep)

This post is a part of the DP-800: Developing AI-Enabled Database Solutions Exam Prep Hub.
This topic falls under these sections:
Design and develop database solutions (35–40%)
   --> Write advanced T-SQL code
      --> Write queries that include fuzzy string matching functions, such as EDIT_DISTANCE, EDIT_DISTANCE_SIMILARITY, and JARO_WINKLER_DISTANCE


Note that there are 10 practice questions (with answers) at the end of each section to help you solidify your knowledge of the material. Also, there are 4 practice tests with 30 questions each available from the hub's main page below the exam topics section.

Introduction

Traditional string comparisons in SQL use operators such as = and LIKE, which require an exact or pattern-based match. However, real-world data is often inconsistent. Misspellings, abbreviations, typographical errors, and formatting differences frequently occur in customer names, product descriptions, addresses, emails, and other text fields.

To address these challenges, SQL Server 2025 (17.x) Preview and Azure SQL Database introduce native fuzzy string matching functions. These functions measure how similar two strings are rather than requiring them to match exactly.

For the DP-800: Developing AI-Enabled Database Solutions certification exam, understanding fuzzy matching is valuable because AI-enabled applications frequently work with imperfect or human-generated text. Fuzzy matching can improve search accuracy, data quality, duplicate detection, and entity matching.

The primary fuzzy matching functions include:

  • EDIT_DISTANCE()
  • EDIT_DISTANCE_SIMILARITY()
  • JARO_WINKLER_DISTANCE()

These functions allow developers to compare strings and determine how closely they resemble one another.

Exam Note: These fuzzy matching functions are new capabilities introduced in SQL Server 2025 (17.x) Preview and Azure SQL Database. They represent Microsoft’s modern approach to intelligent text processing and may appear in newer versions of the DP-800 exam.


What is Fuzzy String Matching?

Fuzzy string matching compares two strings and determines how similar they are, even if they are not identical.

For example:

String 1String 2Similar?
MicrosoftMicrosoftYes
Jon SmithJohn SmithYes
ContosoContoso LtdYes
DatabaseDatabazeYes
AzureAmazonNo

Unlike an equality comparison (=), fuzzy matching recognizes that many differences are minor typographical variations.


Why Fuzzy Matching Matters

Organizations often receive data from multiple sources:

  • Customer registration forms
  • Web applications
  • Mobile apps
  • AI chatbots
  • OCR (Optical Character Recognition)
  • Voice transcription
  • External APIs
  • CSV imports

These data sources often contain spelling mistakes or inconsistent formatting.

Examples include:

OriginalVariation
JonathanJonathon
KatherineCatherine
MicrosoftMicrosft
OrlandoOrlando
SQL ServerSQLServer

Traditional SQL comparisons fail to recognize these values as similar, whereas fuzzy matching functions can identify likely matches.


Understanding Edit Distance

The Edit Distance (also known as the Levenshtein distance) measures the minimum number of operations required to transform one string into another.

The allowed operations are:

  • Insert a character
  • Delete a character
  • Replace a character

Example:

CAT
CUT

Only one substitution is required:

A → U

Edit distance = 1

Another example:

Microsoft
Microsft

Only one missing letter (“o”).

Edit distance = 1

The lower the edit distance, the more similar the strings.


EDIT_DISTANCE()

Purpose

Returns the minimum number of character edits required to convert one string into another.

Syntax

EDIT_DISTANCE(string1, string2)

Example

SELECT EDIT_DISTANCE(
'Microsoft',
'Microsft'
);

Output

1

Example

SELECT EDIT_DISTANCE(
'Database',
'Databaze'
);

Output

1

Example

SELECT EDIT_DISTANCE(
'Azure',
'Amazon'
);

Output

5

A larger number indicates the strings are less similar.


Common Uses of EDIT_DISTANCE()

  • Duplicate customer detection
  • Name matching
  • Address matching
  • Product matching
  • AI-generated text validation
  • OCR correction
  • Search suggestions
  • Data cleansing

EDIT_DISTANCE_SIMILARITY()

Purpose

Returns a similarity score rather than the number of edits.

Instead of measuring differences, this function measures similarity.

Syntax

EDIT_DISTANCE_SIMILARITY(
string1,
string2
)

The function returns a percentage-like similarity score.

Higher values indicate greater similarity.

Example

SELECT EDIT_DISTANCE_SIMILARITY(
'Jonathan',
'Jonathon'
);

Possible output

89

Example

SELECT EDIT_DISTANCE_SIMILARITY(
'SQL Server',
'SQL Server'
);

Output

100

Example

SELECT EDIT_DISTANCE_SIMILARITY(
'Azure',
'Amazon'
);

Possible output

20

Interpreting Similarity Scores

SimilarityMeaning
100Exact match
90–99Nearly identical
75–89Likely match
50–74Possibly related
Below 50Usually unrelated

Developers commonly define thresholds depending on business requirements.

For example:

Similarity >= 90

might be considered an automatic match.


JARO_WINKLER_DISTANCE()

Purpose

Measures similarity using the Jaro-Winkler algorithm, which gives additional weight to matching prefixes.

This algorithm performs particularly well for:

  • Person names
  • Company names
  • City names
  • Street names

Because many spelling variations occur toward the end of words, Jaro-Winkler favors strings that begin similarly.

Example

John
Jon

Very high similarity.

Example

Jonathan
Jonathon

High similarity.

Example

Smith
Smyth

High similarity.


Syntax

JARO_WINKLER_DISTANCE(
string1,
string2
)

Example

SELECT JARO_WINKLER_DISTANCE(
'Jonathan',
'Jonathon'
);

Possible output

0.08

Lower values indicate the strings are more alike (with 0 representing an exact match).


Edit Distance vs. Jaro-Winkler

FeatureEDIT_DISTANCEJARO_WINKLER_DISTANCE
MeasuresCharacter editsOverall similarity
Best forGeneral textNames
Handles typosExcellentExcellent
Considers prefixesNoYes
Duplicate detectionYesYes
Name matchingGoodExcellent

Real-World Business Scenarios

Customer Deduplication

John Smith
Jon Smith

Likely the same customer.


Product Matching

Surface Laptop
Surface Laptp

Typographical error.


Address Matching

123 Main Street
123 Main St.

Likely identical location.


OCR Cleanup

OCR software may read:

Micr0soft

instead of

Microsoft

Fuzzy matching helps identify the intended value.


AI Output Validation

Large language models occasionally generate slight variations:

SQL Sever

instead of

SQL Server

Fuzzy matching can detect likely errors before data is stored.


AI-Enabled Database Scenarios

These functions are especially useful in AI-powered database solutions.

Examples include:

  • Matching chatbot responses to known products
  • Detecting duplicate support tickets
  • Matching customer names across systems
  • Validating OCR-generated text
  • Comparing AI-generated summaries
  • Detecting near-duplicate documents
  • Matching vector-search metadata
  • Intelligent search suggestions
  • Auto-correcting user input
  • Identity resolution

Performance Considerations

Fuzzy matching functions perform more computation than exact string comparisons.

Best practices include:

  • Filter data before applying fuzzy matching.
  • Use indexes to reduce the number of candidate rows.
  • Avoid comparing every row to every other row.
  • Use similarity thresholds to eliminate weak matches.
  • Test performance on production-sized datasets.
  • Consider precomputing or caching similarity scores for frequently compared values.
  • Use fuzzy matching only when exact matching is insufficient.

Best Practices

  • Normalize text before comparison (trim spaces, consistent casing, remove unnecessary punctuation).
  • Use exact matching whenever possible for better performance.
  • Choose appropriate similarity thresholds for your business requirements.
  • Use EDIT_DISTANCE() when you need the number of edits.
  • Use EDIT_DISTANCE_SIMILARITY() when you need an intuitive similarity score.
  • Use JARO_WINKLER_DISTANCE() for names and identity matching.
  • Validate results before automatically merging records.
  • Benchmark fuzzy matching against realistic datasets.

Common Exam Tips

Remember these key points for the DP-800 exam:

  • Fuzzy matching compares similarity rather than exact equality.
  • EDIT_DISTANCE() returns the number of edits needed to transform one string into another.
  • Smaller edit distances indicate greater similarity.
  • EDIT_DISTANCE_SIMILARITY() returns a normalized similarity score, where higher values represent more similar strings.
  • JARO_WINKLER_DISTANCE() emphasizes matching prefixes and is particularly effective for comparing names.
  • Fuzzy matching is useful for data quality, duplicate detection, AI-generated content validation, OCR cleanup, and intelligent search.
  • Because fuzzy matching is computationally intensive, use it selectively and after narrowing the candidate set when possible.

Practice Exam Questions

Question 1

A company imports customer records from multiple systems. Which function is best suited to determine the minimum number of character changes required to transform one customer name into another?

A. EDIT_DISTANCE()

B. EDIT_DISTANCE_SIMILARITY()

C. JARO_WINKLER_DISTANCE()

D. LIKE

Answer: A

Explanation: EDIT_DISTANCE() calculates the minimum number of insertions, deletions, and substitutions needed to transform one string into another.


Question 2

Which fuzzy matching function returns a normalized similarity score where higher values indicate more similar strings?

A. REGEXP_LIKE()

B. JARO_WINKLER_DISTANCE()

C. EDIT_DISTANCE_SIMILARITY()

D. CHARINDEX()

Answer: C

Explanation: EDIT_DISTANCE_SIMILARITY() converts the edit distance into a similarity score, making it easier to establish matching thresholds.


Question 3

A database developer is comparing customer names such as “John” and “Jon.” Which function is generally most appropriate?

A. EDIT_DISTANCE()

B. PATINDEX()

C. LIKE

D. JARO_WINKLER_DISTANCE()

Answer: D

Explanation: Jaro-Winkler is particularly effective for comparing names because it gives additional weight to matching prefixes.


Question 4

What does an EDIT_DISTANCE() value of 0 indicate?

A. The strings are unrelated.

B. One string contains only numbers.

C. The strings are identical.

D. The comparison failed.

Answer: C

Explanation: An edit distance of zero means no insertions, deletions, or substitutions are required because the strings are identical.


Question 5

Which scenario is the best candidate for fuzzy string matching?

A. Comparing integer primary keys.

B. Matching customer names entered manually.

C. Sorting dates.

D. Calculating sales totals.

Answer: B

Explanation: Fuzzy matching is designed to compare imperfect text, such as names entered by users that may contain spelling variations.


Question 6

Why should fuzzy matching generally be applied after filtering candidate rows?

A. It prevents SQL injection.

B. It automatically creates indexes.

C. It reduces computational cost and improves query performance.

D. It guarantees exact matches.

Answer: C

Explanation: Fuzzy matching algorithms are more expensive than exact comparisons, so reducing the candidate set improves performance.


Question 7

Which statement about JARO_WINKLER_DISTANCE() is correct?

A. It counts the number of vowels in a string.

B. It gives additional weight to matching prefixes.

C. It replaces text using regular expressions.

D. It returns the number of character edits.

Answer: B

Explanation: The Jaro-Winkler algorithm favors strings that share the same beginning, making it particularly useful for matching names.


Question 8

Which of the following is a common AI-enabled use case for fuzzy string matching?

A. Creating clustered indexes.

B. Encrypting sensitive columns.

C. Detecting likely duplicate support tickets generated by AI systems.

D. Managing SQL Server backups.

Answer: C

Explanation: AI-generated text may contain slight wording differences, making fuzzy matching valuable for identifying duplicate or highly similar records.


Question 9

A similarity score of 100 returned by EDIT_DISTANCE_SIMILARITY() most likely indicates:

A. The strings are completely different.

B. The strings have five character differences.

C. The comparison failed.

D. The strings are identical.

Answer: D

Explanation: A score of 100 represents an exact match between the two strings.


Question 10

Which statement best describes fuzzy string matching?

A. It requires strings to be identical.

B. It compares the similarity between strings, even when they contain typographical errors.

C. It is designed exclusively for JSON processing.

D. It replaces SQL indexes.

Answer: B

Explanation: Fuzzy matching measures similarity rather than exact equality, making it useful for handling misspellings, abbreviations, and other textual variations.


Go to the DP-800 Exam Prep Hub main page

Write queries that include regular expressions, such as REGEXP_LIKE, REGEXP_REPLACE, REGEXP_SUBSTR, REGEXP_INSTR, REGEXP_COUNT, REGEXP_MATCHES, and REGEXP_SPLIT_TO_TABLE (DP-800 Exam Prep)

This post is a part of the DP-800: Developing AI-Enabled Database Solutions Exam Prep Hub.
This topic falls under these sections:
Design and develop database solutions (35–40%)
   --> Write advanced T-SQL code
      --> Write queries that include regular expressions, such as REGEXP_LIKE, REGEXP_REPLACE, REGEXP_SUBSTR, REGEXP_INSTR, REGEXP_COUNT, REGEXP_MATCHES, and REGEXP_SPLIT_TO_TABLE


Note that there are 10 practice questions (with answers) at the end of each section to help you solidify your knowledge of the material. Also, there are 4 practice tests with 30 questions each available from the hub's main page below the exam topics section.

Introduction

Regular expressions (regex) are powerful pattern-matching expressions used to search, validate, extract, replace, and manipulate text. They have been available in many programming languages for years and are now available in SQL Server 2025 (17.x) Preview and Azure SQL Database through native T-SQL regular expression functions.

For developers, regex significantly simplifies many text-processing tasks that previously required combinations of LIKE, PATINDEX, CHARINDEX, SUBSTRING, REPLACE, and custom T-SQL logic.

For the DP-800: Developing AI-Enabled Database Solutions exam, understanding these functions is increasingly important because AI-enabled applications frequently process:

  • User prompts
  • Chat conversations
  • Log files
  • Emails
  • Product descriptions
  • Documents
  • JSON data
  • Metadata
  • Search indexes

Regular expressions allow SQL Server to efficiently validate, search, and transform this semi-structured text.


What is a Regular Expression?

A regular expression is a sequence of characters that defines a search pattern.

For example:

PatternMeaning
\dAny digit
[A-Z]Uppercase letter
[a-z]Lowercase letter
[A-Za-z]Any letter
.Any character
.*Zero or more characters
+One or more occurrences
?Optional occurrence
^Beginning of string
$End of string
\sWhitespace
\wWord character
[^0-9]Anything except digits

Example:

^\d{5}$

Matches exactly five digits.

Examples:

12345 ✔
98765 ✔
1234 ✘
123456 ✘
ABCDE ✘

SQL Server Regular Expression Functions

The newest T-SQL regular expression functions include:

  • REGEXP_LIKE()
  • REGEXP_REPLACE()
  • REGEXP_SUBSTR()
  • REGEXP_INSTR()
  • REGEXP_COUNT()
  • REGEXP_MATCHES()
  • REGEXP_SPLIT_TO_TABLE()

Each function serves a different purpose.


REGEXP_LIKE()

Purpose

Tests whether text matches a regular expression.

Syntax

REGEXP_LIKE(expression, pattern)

Example

SELECT CustomerEmail
FROM Customers
WHERE REGEXP_LIKE(
CustomerEmail,
'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'
);

This returns only rows containing valid email addresses.

Common Uses

  • Validate email addresses
  • Validate ZIP codes
  • Validate phone numbers
  • Validate product codes
  • Validate license numbers
  • Check AI-generated output

REGEXP_REPLACE()

Purpose

Replaces matching text.

Syntax

REGEXP_REPLACE(expression, pattern, replacement)

Example

Remove non-numeric characters from a phone number.

SELECT REGEXP_REPLACE(
'(555) 123-4567',
'[^0-9]',
''
);

Output

5551234567

Example

Replace multiple spaces with one space.

SELECT REGEXP_REPLACE(
'John Smith',
'\s+',
' '
);

Output

John Smith

Common Uses

  • Data cleansing
  • Standardization
  • Removing punctuation
  • Removing HTML tags
  • Cleaning AI responses

REGEXP_SUBSTR()

Purpose

Returns the first substring that matches a pattern.

Syntax

REGEXP_SUBSTR(expression, pattern)

Example

SELECT REGEXP_SUBSTR(
'Invoice #INV-2025-1045',
'INV-[0-9-]+'
);

Output

INV-2025-1045

Useful for extracting:

  • Invoice numbers
  • Tracking numbers
  • Product IDs
  • URLs
  • Dates

REGEXP_INSTR()

Purpose

Returns the starting position of a pattern.

Syntax

REGEXP_INSTR(expression, pattern)

Example

SELECT REGEXP_INSTR(
'Customer ID: 12345',
'\d+'
);

Output

14

If no match exists, the function returns 0.


REGEXP_COUNT()

Purpose

Counts how many times a pattern occurs.

Syntax

REGEXP_COUNT(expression, pattern)

Example

SELECT REGEXP_COUNT(
'cat dog cat bird cat',
'cat'
);

Output

3

Useful for:

  • Counting hashtags
  • Counting keywords
  • Counting repeated words
  • Measuring AI response quality

REGEXP_MATCHES()

Purpose

Returns all substrings that match a pattern.

Unlike REGEXP_SUBSTR(), which returns only the first match, REGEXP_MATCHES() returns every match.

Example

SELECT *
FROM REGEXP_MATCHES(
'Phone: 555-1111 Office: 555-2222',
'\d{3}-\d{4}'
);

Output

555-1111
555-2222

Common uses include:

  • Finding all phone numbers
  • Extracting URLs
  • Extracting hashtags
  • Finding dates

REGEXP_SPLIT_TO_TABLE()

Purpose

Splits text into rows using a regular expression delimiter.

Example

SELECT *
FROM REGEXP_SPLIT_TO_TABLE(
'SQL,Azure,AI,Python',
','
);

Output

Value
SQL
Azure
AI
Python

Example

Split on one or more spaces.

SELECT *
FROM REGEXP_SPLIT_TO_TABLE(
'SQL Azure AI',
'\s+'
);

Comparing the Functions

FunctionPurpose
REGEXP_LIKE()Test whether text matches a pattern
REGEXP_REPLACE()Replace matching text
REGEXP_SUBSTR()Return first matching substring
REGEXP_INSTR()Return position of first match
REGEXP_COUNT()Count matches
REGEXP_MATCHES()Return all matches
REGEXP_SPLIT_TO_TABLE()Split text into rows

Common Regular Expression Patterns

Email

^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$

US ZIP Code

^\d{5}$

ZIP+4

^\d{5}-\d{4}$

Phone Number

^\(?\d{3}\)?[- ]?\d{3}[- ]?\d{4}$

GUID

^[0-9A-Fa-f-]{36}$

URL

https?://.*

Integer

^\d+$

Decimal Number

^\d+\.\d+$

AI-Enabled Database Scenarios

Regular expressions are especially valuable when AI applications generate or consume semi-structured text.

Examples include:

  • Validating AI-generated email addresses
  • Extracting invoice numbers from chatbot responses
  • Cleaning OCR text
  • Removing HTML from generated content
  • Parsing metadata
  • Detecting URLs in AI responses
  • Validating JSON fragments
  • Finding sensitive information before storage
  • Identifying product codes
  • Processing vector search metadata

Performance Considerations

Regular expressions are more computationally expensive than simple string comparisons.

To improve performance:

  • Use simple patterns whenever possible.
  • Filter rows before applying regex functions.
  • Avoid leading wildcards when simpler predicates suffice.
  • Avoid unnecessarily complex nested expressions.
  • Consider computed columns for frequently evaluated values.
  • Benchmark regex queries on large datasets.
  • Use indexes to reduce the number of rows that require regex evaluation.

Best Practices

  • Keep patterns simple and readable.
  • Test regex thoroughly using representative data.
  • Escape special characters when needed.
  • Validate user-supplied patterns to prevent errors.
  • Use anchors (^ and $) when matching an entire string.
  • Use character classes instead of long OR conditions.
  • Prefer regex only when simpler string functions cannot meet the requirement.
  • Document complex expressions for maintainability.
  • Handle NULL values appropriately.
  • Monitor performance on large datasets.

Common Exam Tips

For the DP-800 exam, remember:

  • REGEXP_LIKE() validates or filters text.
  • REGEXP_REPLACE() modifies text.
  • REGEXP_SUBSTR() extracts the first match.
  • REGEXP_INSTR() returns the position of a match.
  • REGEXP_COUNT() counts pattern occurrences.
  • REGEXP_MATCHES() returns all matches.
  • REGEXP_SPLIT_TO_TABLE() converts delimited text into rows.
  • Regular expressions are ideal for processing semi-structured text used by AI-enabled applications.
  • Regex offers significantly more flexibility than LIKE and PATINDEX for complex pattern matching.

Practice Exam Questions

Question 1

A developer needs to validate that a column contains only properly formatted email addresses. Which function should be used?

A. REGEXP_REPLACE()

B. REGEXP_LIKE()

C. REGEXP_SUBSTR()

D. REGEXP_COUNT()

Answer: B

Explanation: REGEXP_LIKE() evaluates whether a string matches a regular expression and is the appropriate function for validating email formats.


Question 2

You need to remove all punctuation from customer phone numbers before storing them. Which function is most appropriate?

A. REGEXP_REPLACE()

B. REGEXP_INSTR()

C. REGEXP_MATCHES()

D. REGEXP_COUNT()

Answer: A

Explanation: REGEXP_REPLACE() replaces matching characters or patterns, making it ideal for removing punctuation or formatting characters.


Question 3

A product description contains multiple serial numbers, and you need to return every matching serial number. Which function should you use?

A. REGEXP_SUBSTR()

B. REGEXP_COUNT()

C. REGEXP_MATCHES()

D. REGEXP_LIKE()

Answer: C

Explanation: REGEXP_MATCHES() returns all occurrences that satisfy the specified regular expression rather than just the first match.


Question 4

You need to extract the first invoice number from a block of text. Which function is the best choice?

A. REGEXP_SPLIT_TO_TABLE()

B. REGEXP_INSTR()

C. REGEXP_SUBSTR()

D. REGEXP_REPLACE()

Answer: C

Explanation: REGEXP_SUBSTR() extracts and returns the first substring that matches the specified regular expression.


Question 5

Which function returns the character position where the first match begins?

A. REGEXP_INSTR()

B. REGEXP_COUNT()

C. REGEXP_MATCHES()

D. REGEXP_REPLACE()

Answer: A

Explanation: REGEXP_INSTR() returns the starting position of the first occurrence of a pattern within a string.


Question 6

A developer needs to determine how many times the word “error” appears in a log entry. Which function should be used?

A. REGEXP_MATCHES()

B. REGEXP_COUNT()

C. REGEXP_SUBSTR()

D. REGEXP_LIKE()

Answer: B

Explanation: REGEXP_COUNT() counts the number of occurrences of a pattern within a string.


Question 7

A comma-separated list stored in a column must be converted into one row per value. Which function is designed for this task?

A. REGEXP_REPLACE()

B. REGEXP_INSTR()

C. REGEXP_SPLIT_TO_TABLE()

D. REGEXP_SUBSTR()

Answer: C

Explanation: REGEXP_SPLIT_TO_TABLE() divides a string into multiple rows using a regular expression as the delimiter.


Question 8

Which regular expression pattern matches exactly five digits?

A. \d+

B. ^\d{5}$

C. \d{5,}

D. [0-9]*

Answer: B

Explanation: ^\d{5}$ anchors the match to the beginning and end of the string and requires exactly five digits.


Question 9

Why are regular expressions particularly valuable in AI-enabled database solutions?

A. They automatically train AI models.

B. They replace JSON processing.

C. They eliminate the need for SQL indexes.

D. They efficiently validate, extract, and transform semi-structured text generated by AI systems.

Answer: D

Explanation: AI applications frequently exchange semi-structured text, and regex functions simplify validation, extraction, cleansing, and transformation directly within SQL.


Question 10

When should you prefer regular expressions over simple string functions such as LIKE?

A. For every text comparison.

B. Only when searching numeric columns.

C. When complex pattern matching or text extraction is required.

D. Only when working with JSON data.

Answer: C

Explanation: Regular expressions are best suited for sophisticated pattern matching, validation, and extraction tasks that cannot be easily implemented using simpler string functions.


Go to the DP-800 Exam Prep Hub main page

Write queries that include JSON functions (DP-800 Exam Prep)

This post is a part of the DP-800: Developing AI-Enabled Database Solutions Exam Prep Hub.
This topic falls under these sections:
Design and develop database solutions (35–40%)
   --> Write advanced T-SQL code
      --> Write queries that include JSON functions


Note that there are 10 practice questions (with answers) at the end of each section to help you solidify your knowledge of the material. Also, there are 4 practice tests with 30 questions each available from the hub's main page below the exam topics section.

Introduction

JSON (JavaScript Object Notation) has become one of the most common formats for exchanging and storing structured data in modern applications. SQL Server and Azure SQL Database provide native JSON support that allows developers to parse, query, modify, and generate JSON data without requiring a separate document database.

For the DP-800: Developing AI-Enabled Database Solutions certification exam, you should understand how to use T-SQL JSON functions to work with JSON documents stored in SQL Server tables or received from external applications and services. JSON capabilities are particularly valuable when integrating relational databases with REST APIs, cloud services, AI applications, and modern web applications.

Unlike XML, SQL Server does not have a dedicated JSON data type (in generally available releases covered by the current DP-800 learning content). Instead, JSON documents are typically stored in nvarchar columns and processed using built-in JSON functions.

This article covers the JSON functionality emphasized in the current Microsoft Learn curriculum, including:

  • Understanding JSON in SQL Server
  • Validating JSON documents
  • Extracting scalar values
  • Extracting objects and arrays
  • Parsing JSON into relational rows
  • Modifying JSON documents
  • Returning JSON from queries
  • Performance considerations
  • AI-enabled database scenarios
  • Best practices

Understanding JSON in SQL Server

JSON represents data as key-value pairs and arrays.

Example JSON document:

{
"CustomerID": 1001,
"Name": "John Smith",
"Email": "john@contoso.com",
"Orders": [
{
"OrderID": 501,
"Amount": 250.00
},
{
"OrderID": 502,
"Amount": 120.00
}
]
}

SQL Server stores JSON as plain text but provides functions that understand the JSON structure.


JSON Support in SQL Server

The primary JSON features include:

  • ISJSON()
  • JSON_VALUE()
  • JSON_QUERY()
  • JSON_MODIFY()
  • OPENJSON
  • FOR JSON

These functions allow developers to:

  • Validate JSON
  • Retrieve values
  • Retrieve arrays and objects
  • Update JSON documents
  • Convert JSON into relational tables
  • Generate JSON output

ISJSON()

ISJSON() determines whether a string contains valid JSON.

Syntax:

ISJSON(expression)

Example:

SELECT ISJSON('{"Name":"John"}');

Result:

1

Invalid JSON returns:

0

Common use cases include:

  • Data validation
  • Import validation
  • Preventing malformed JSON from entering the database

JSON_VALUE()

JSON_VALUE() extracts a single scalar value from a JSON document.

Syntax:

JSON_VALUE(expression, path)

Example:

SELECT JSON_VALUE(
'{
"Customer":
{
"Name":"John Smith"
}
}',
'$.Customer.Name');

Result:

John Smith

JSON_VALUE() returns values such as:

  • Strings
  • Numbers
  • Dates
  • Booleans

It does not return JSON objects or arrays.


JSON Path Expressions

JSON functions use path expressions to locate data.

Examples:

PathMeaning
$Root object
$.CustomerCustomer object
$.Customer.NameName property
$.Orders[0]First order
$.Orders[1].AmountAmount of second order

Understanding JSON path syntax is an important DP-800 exam objective.


JSON_QUERY()

JSON_QUERY() extracts an object or an array instead of a scalar value.

Example:

SELECT JSON_QUERY(
'{
"Orders":
[
{"OrderID":1},
{"OrderID":2}
]
}',
'$.Orders');

Result:

[
{"OrderID":1},
{"OrderID":2}
]

Use JSON_QUERY() whenever the requested value is another JSON object or array.


JSON_VALUE() vs. JSON_QUERY()

JSON_VALUE()JSON_QUERY()
Returns a scalar valueReturns an object or array
Returns textReturns JSON
Used for individual propertiesUsed for nested objects and arrays

Choosing the correct function is a common exam topic.


OPENJSON

OPENJSON converts JSON into relational rows and columns.

Example:

DECLARE @Orders nvarchar(max) =
'[
{"OrderID":101,"Amount":150},
{"OrderID":102,"Amount":250}
]';
SELECT *
FROM OPENJSON(@Orders);

Result:

KeyValueType
0{…}5
1{…}5

OPENJSON WITH Clause

The WITH clause maps JSON properties to columns.

Example:

DECLARE @Orders nvarchar(max) =
'[
{"OrderID":101,"Amount":150},
{"OrderID":102,"Amount":250}
]';
SELECT *
FROM OPENJSON(@Orders)
WITH
(
OrderID int,
Amount decimal(10,2)
);

Result:

OrderIDAmount
101150.00
102250.00

This is the preferred method when importing structured JSON into SQL tables.


JSON_MODIFY()

JSON_MODIFY() updates a JSON document.

Example:

DECLARE @Customer nvarchar(max)=
'{"Name":"John","City":"Seattle"}';
SELECT JSON_MODIFY(
@Customer,
'$.City',
'Orlando');

Result:

{
"Name":"John",
"City":"Orlando"
}

JSON_MODIFY() can:

  • Update values
  • Insert properties
  • Delete properties by assigning NULL

FOR JSON

FOR JSON converts SQL query results into JSON.

Example:

SELECT
CustomerID,
Name
FROM Customers
FOR JSON AUTO;

Output:

[
{
"CustomerID":1,
"Name":"John"
},
{
"CustomerID":2,
"Name":"Mary"
}
]

FOR JSON AUTO vs. FOR JSON PATH

FOR JSON AUTO

Automatically generates JSON based on table structure.

Example:

SELECT CustomerID, Name
FROM Customers
FOR JSON AUTO;

Little customization is available.


FOR JSON PATH

Provides complete control over the generated JSON structure.

Example:

SELECT
CustomerID AS "Customer.ID",
Name AS "Customer.Name"
FROM Customers
FOR JSON PATH;

This allows nested objects and custom property names.


Working with Nested JSON

Example:

{
"Customer":
{
"Name":"John",
"Address":
{
"City":"Orlando"
}
}
}

Retrieve the city:

SELECT JSON_VALUE(
@Customer,
'$.Customer.Address.City');

Loading JSON into Tables

Example:

INSERT INTO Orders(OrderID, Amount)
SELECT OrderID, Amount
FROM OPENJSON(@Orders)
WITH
(
OrderID int,
Amount decimal(10,2)
);

This approach is frequently used when consuming REST APIs.


Returning JSON from Stored Procedures

Stored procedures often return JSON to client applications.

Example:

SELECT *
FROM Customers
FOR JSON PATH;

Applications can consume the JSON without additional transformation.


JSON and Azure Services

JSON is widely used with:

  • Azure Functions
  • Azure Logic Apps
  • Azure App Service
  • Azure API Management
  • REST APIs
  • Power Apps
  • Power Automate

JSON enables efficient communication between SQL databases and cloud-based applications.


AI-Enabled Database Scenarios

JSON plays a significant role in AI-enabled solutions because many AI services exchange information using JSON documents.

Common scenarios include:

  • Receiving prompts from client applications
  • Storing AI model responses
  • Logging chatbot conversations
  • Storing document metadata
  • Integrating Azure AI services
  • Consuming REST APIs
  • Passing structured data to Retrieval-Augmented Generation (RAG) pipelines
  • Returning AI-generated content to applications

For example, a SQL stored procedure might accept a JSON request from an application, extract values with JSON_VALUE() or OPENJSON, query relational data, and return results as JSON using FOR JSON PATH.


Emerging JSON Functions (SQL Server 2025 and Azure SQL Database)

Recent versions of Azure SQL Database and SQL Server introduce additional JSON functions that make it easier to construct, aggregate, and search JSON data directly within SQL queries. While these functions are newer than the core JSON functions covered earlier, they represent the future direction of SQL Server’s native JSON capabilities and are useful to understand.

These functions include:

  • JSON_OBJECT()
  • JSON_ARRAY()
  • JSON_ARRAYAGG()
  • JSON_OBJECTAGG()
  • JSON_CONTAINS()

JSON_OBJECT()

JSON_OBJECT() creates a JSON object directly from key-value pairs.

Instead of manually concatenating strings, SQL Server automatically generates properly formatted JSON.

Syntax:

JSON_OBJECT(
'key1': value1,
'key2': value2
)

Example:

SELECT JSON_OBJECT(
'CustomerID': CustomerID,
'Name': CustomerName,
'City': City
)
FROM Customers;

Possible output:

{
"CustomerID": 101,
"Name": "John Smith",
"City": "Seattle"
}

Benefits

  • Simpler than string concatenation
  • Automatically escapes special characters
  • Produces valid JSON
  • Easier to read and maintain

JSON_ARRAY()

JSON_ARRAY() creates a JSON array from one or more values.

Syntax:

JSON_ARRAY(value1, value2, value3)

Example:

SELECT JSON_ARRAY(
'SQL',
'Azure',
'AI',
'JSON'
);

Output:

[
"SQL",
"Azure",
"AI",
"JSON"
]

Arrays may contain:

  • Strings
  • Numbers
  • Boolean values
  • NULL values
  • Nested JSON objects

This function is particularly useful when returning lists to applications and APIs.


JSON_ARRAYAGG()

JSON_ARRAYAGG() aggregates multiple rows into a single JSON array.

It performs a role similar to STRING_AGG(), but returns properly formatted JSON instead of plain text.

Example:

SELECT JSON_ARRAYAGG(CustomerName)
FROM Customers;

Output:

[
"John",
"Mary",
"Susan",
"David"
]

It can also aggregate JSON objects.

Example:

SELECT JSON_ARRAYAGG(
JSON_OBJECT(
'ID': CustomerID,
'Name': CustomerName
)
)
FROM Customers;

Output:

[
{
"ID":101,
"Name":"John"
},
{
"ID":102,
"Name":"Mary"
}
]

Common Uses

  • REST API responses
  • AI service payloads
  • Returning collections of objects
  • Building hierarchical JSON documents

JSON_OBJECTAGG()

JSON_OBJECTAGG() aggregates multiple rows into a single JSON object.

Each row contributes a key-value pair.

Example:

SELECT JSON_OBJECTAGG(
DepartmentName : EmployeeCount
)
FROM DepartmentSummary;

Possible output:

{
"Sales":42,
"Finance":18,
"HR":11
}

This function is useful when applications require lookup-style JSON objects rather than arrays.

Common scenarios include:

  • Configuration settings
  • Summary statistics
  • Name/value collections
  • Metadata dictionaries

JSON_CONTAINS()

JSON_CONTAINS() determines whether a JSON document contains a specified value or object.

Example:

SELECT JSON_CONTAINS(
'{"Skills":["SQL","Azure","AI"]}',
'"Azure"',
'$.Skills'
);

Result:

1

A return value of:

  • 1 indicates the value exists.
  • 0 indicates it does not exist.

Unlike JSON_VALUE(), which retrieves a value, JSON_CONTAINS() is intended for searching JSON documents.

Typical uses include:

  • Searching arrays
  • Validating configuration values
  • Checking permissions stored as JSON
  • Verifying tags or categories
  • Filtering semi-structured data

Comparing the JSON Functions

FunctionPurposeReturns
ISJSON()Validate JSONInteger
JSON_VALUE()Retrieve a scalar valueScalar
JSON_QUERY()Retrieve an object or arrayJSON
JSON_MODIFY()Update JSONJSON
OPENJSONConvert JSON to rowsTable
FOR JSONGenerate JSON from query resultsJSON
JSON_OBJECT()Create a JSON objectJSON
JSON_ARRAY()Create a JSON arrayJSON
JSON_ARRAYAGG()Aggregate rows into a JSON arrayJSON
JSON_OBJECTAGG()Aggregate rows into a JSON objectJSON
JSON_CONTAINS()Test whether JSON contains a valueBoolean (1/0)

AI-Enabled Database Scenarios

These newer JSON functions are especially useful in AI-enabled database solutions because AI applications frequently exchange complex JSON payloads.

Examples include:

  • Creating structured prompts for large language models (LLMs)
  • Returning Retrieval-Augmented Generation (RAG) results as JSON arrays
  • Building JSON responses for Azure AI Foundry or Azure OpenAI applications
  • Aggregating search results into JSON collections for APIs
  • Constructing metadata objects for vector search and embeddings
  • Verifying whether AI-generated JSON responses contain required fields or values

By generating JSON natively within SQL Server, these functions reduce the need for application-side serialization and simplify integrations with cloud services and AI workflows.


Performance Considerations

Because JSON is stored as text, SQL Server must parse the document during queries.

Performance can be improved by:

  • Storing only necessary JSON data
  • Using computed columns that extract frequently queried properties
  • Creating indexes on persisted computed columns
  • Avoiding repeated parsing of large JSON documents
  • Using OPENJSON with a WITH clause for structured imports

Best Practices

  • Validate incoming JSON using ISJSON().
  • Use JSON_VALUE() for scalar values.
  • Use JSON_QUERY() for arrays and objects.
  • Use OPENJSON to convert JSON into relational rows.
  • Use JSON_MODIFY() to update JSON documents.
  • Use FOR JSON PATH when customized output is required.
  • Store JSON only when relational columns are not appropriate.
  • Index frequently queried JSON properties through computed columns.
  • Validate JSON path expressions during development.
  • Keep JSON documents reasonably sized to improve performance.

Common Exam Tips

For the DP-800 exam, remember the following:

  • SQL Server stores JSON in nvarchar columns.
  • ISJSON() validates JSON.
  • JSON_VALUE() returns scalar values.
  • JSON_QUERY() returns objects and arrays.
  • JSON_MODIFY() updates JSON documents.
  • OPENJSON converts JSON into relational rows.
  • OPENJSON WITH maps JSON properties to typed columns.
  • FOR JSON AUTO automatically formats query results.
  • FOR JSON PATH provides greater control over the JSON output.
  • JSON is commonly used when integrating SQL Server with cloud services, APIs, and AI applications.

Practice Exam Questions

Question 1

Which function validates whether a string contains properly formatted JSON?

A. JSON_QUERY()

B. JSON_MODIFY()

C. OPENJSON

D. ISJSON()

Answer: D

Explanation: ISJSON() returns 1 for valid JSON and 0 for invalid JSON, making it useful for validating incoming data.


Question 2

Which function should you use to extract a single scalar value such as a customer’s name from a JSON document?

A. JSON_QUERY()

B. JSON_VALUE()

C. OPENJSON()

D. FOR JSON

Answer: B

Explanation: JSON_VALUE() returns a single scalar value such as a string, number, or Boolean from a specified JSON path.


Question 3

A developer needs to return an entire JSON array from a document. Which function is appropriate?

A. JSON_QUERY()

B. JSON_VALUE()

C. ISJSON()

D. JSON_MODIFY()

Answer: A

Explanation: JSON_QUERY() returns JSON objects and arrays, whereas JSON_VALUE() returns only scalar values.


Question 4

Which T-SQL feature converts JSON data into relational rows and columns?

A. JSON_VALUE()

B. JSON_QUERY()

C. OPENJSON

D. FOR JSON PATH

Answer: C

Explanation: OPENJSON parses JSON text and returns rows that can be further mapped into relational columns using the WITH clause.


Question 5

Which statement about FOR JSON PATH is correct?

A. It validates JSON documents.

B. It converts JSON into relational tables.

C. It provides control over the structure of generated JSON output.

D. It can only return scalar values.

Answer: C

Explanation: FOR JSON PATH allows developers to customize property names and create nested JSON structures.


Question 6

What is the primary purpose of JSON_MODIFY()?

A. Validate JSON syntax.

B. Retrieve a scalar value.

C. Return an array.

D. Update or insert values within a JSON document.

Answer: D

Explanation: JSON_MODIFY() changes JSON content by updating, inserting, or deleting properties.


Question 7

When importing data from a REST API into SQL Server, which approach provides the most structured mapping between JSON properties and SQL columns?

A. JSON_QUERY()

B. OPENJSON with a WITH clause

C. ISJSON()

D. FOR JSON AUTO

Answer: B

Explanation: The WITH clause allows OPENJSON to map JSON properties directly into strongly typed SQL columns.


Question 8

Which JSON path expression returns the value of the Name property within the Customer object?

A. $.Name.Customer

B. Customer.Name

C. $.Customer.Name

D. $[Customer][Name]

Answer: C

Explanation: JSON path expressions begin at the root ($) and navigate through object properties using dot notation.


Question 9

Why are computed columns often used with JSON data?

A. They convert JSON into XML.

B. They eliminate the need for JSON functions.

C. They allow frequently accessed JSON values to be indexed for improved query performance.

D. They automatically validate JSON syntax.

Answer: C

Explanation: Persisted computed columns can extract JSON properties using JSON_VALUE(), enabling indexes to improve query performance.


Question 10

How are SQL Server JSON functions commonly used in AI-enabled database solutions?

A. They replace relational tables entirely.

B. They create machine learning models directly.

C. They eliminate the need for APIs.

D. They parse, transform, and generate structured JSON exchanged between SQL databases, AI services, REST APIs, and applications.

Answer: D

Explanation: AI services commonly exchange structured JSON payloads. SQL Server JSON functions enable applications to consume, transform, store, and return this data efficiently.


Go to the DP-800 Exam Prep Hub main page

Write queries that include window functions (DP-800 Exam Prep)

This post is a part of the DP-800: Developing AI-Enabled Database Solutions Exam Prep Hub.
This topic falls under these sections:
Design and develop database solutions (35–40%)
   --> Write advanced T-SQL code
      --> Write queries that include window functions


Note that there are 10 practice questions (with answers) at the end of each section to help you solidify your knowledge of the material. Also, there are 4 practice tests with 30 questions each available from the hub's main page below the exam topics section.

Introduction

Window functions are among the most powerful features in Transact-SQL (T-SQL). They enable calculations across a set of rows related to the current row without collapsing the results into a single row, as traditional aggregate functions do. Window functions are widely used in reporting, analytics, business intelligence, financial analysis, and AI-enabled database solutions.

Unlike GROUP BY, which returns one row per group, window functions preserve the individual rows while providing additional calculated values based on a defined “window” of rows.

For the DP-800: Developing AI-Enabled Database Solutions certification exam, you should understand:

  • What window functions are
  • The OVER clause
  • Partitioning data
  • Ordering data within windows
  • Aggregate window functions
  • Ranking functions
  • Offset functions
  • Window frames
  • Practical business scenarios
  • Performance considerations
  • Best practices

Window functions are heavily tested because they allow developers to perform sophisticated calculations efficiently while maintaining readable and maintainable SQL code.


What Is a Window Function?

A window function performs a calculation across a set of rows that are related to the current row.

Unlike aggregate functions used with GROUP BY, a window function does not reduce the number of rows returned.

General syntax:

Function(...) OVER
(
[PARTITION BY column]
[ORDER BY column]
)

The OVER clause defines the window over which the calculation occurs.


The OVER Clause

The OVER clause is required for window functions.

It can contain:

  • PARTITION BY
  • ORDER BY
  • Window frame definitions (ROWS or RANGE)

Example:

SELECT
EmployeeID,
Salary,
AVG(Salary) OVER() AS AverageSalary
FROM HumanResources.Employee;

The average salary is calculated across all employees while each employee row remains visible.


PARTITION BY

PARTITION BY divides the result set into logical groups.

Example:

SELECT
DepartmentID,
EmployeeID,
Salary,
AVG(Salary)
OVER(PARTITION BY DepartmentID)
AS DepartmentAverage
FROM HumanResources.Employee;

Each department receives its own average salary.


ORDER BY Within OVER

The ORDER BY clause defines the order of rows within each partition.

Example:

SELECT
EmployeeID,
Salary,
ROW_NUMBER()
OVER(ORDER BY Salary DESC)
AS SalaryRank
FROM HumanResources.Employee;

The highest salary receives row number 1.


Aggregate Window Functions

Many aggregate functions can operate as window functions.

Common examples include:

  • SUM()
  • AVG()
  • MIN()
  • MAX()
  • COUNT()

Example:

SELECT
CustomerID,
OrderDate,
TotalAmount,
SUM(TotalAmount)
OVER(PARTITION BY CustomerID)
AS CustomerTotal
FROM Sales.Orders;

Each order row displays the customer’s total sales without grouping the results.


Running Totals

A common use of window functions is calculating running totals.

Example:

SELECT
OrderDate,
TotalAmount,
SUM(TotalAmount)
OVER
(
ORDER BY OrderDate
ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW
)
AS RunningTotal
FROM Sales.Orders;

Each row contains the cumulative total through the current row.


Moving Averages

Window functions simplify moving averages.

Example:

SELECT
OrderDate,
SalesAmount,
AVG(SalesAmount)
OVER
(
ORDER BY OrderDate
ROWS BETWEEN 2 PRECEDING
AND CURRENT ROW
)
AS ThreeDayAverage
FROM Sales.DailySales;

This example calculates a rolling average over three rows.


Ranking Functions

SQL Server includes several ranking window functions.

These include:

  • ROW_NUMBER()
  • RANK()
  • DENSE_RANK()
  • NTILE()

ROW_NUMBER()

Assigns a unique sequential number.

Example:

SELECT
EmployeeID,
Salary,
ROW_NUMBER()
OVER(ORDER BY Salary DESC)
AS RowNum
FROM HumanResources.Employee;

Even rows with equal salaries receive different numbers.


RANK()

Assigns rankings while allowing gaps after ties.

Example:

SELECT
EmployeeID,
Salary,
RANK()
OVER(ORDER BY Salary DESC)
AS SalaryRank
FROM HumanResources.Employee;

If two employees tie for first place, the next rank is 3.


DENSE_RANK()

Assigns rankings without gaps.

Example:

SELECT
EmployeeID,
Salary,
DENSE_RANK()
OVER(ORDER BY Salary DESC)
AS SalaryRank
FROM HumanResources.Employee;

If two employees tie for first place, the next rank is 2.


ROW_NUMBER vs. RANK vs. DENSE_RANK

FunctionDuplicate ValuesGaps in Ranking
ROW_NUMBERNoNo
RANKYesYes
DENSE_RANKYesNo

Understanding these differences is a common DP-800 exam objective.


NTILE()

NTILE() divides rows into approximately equal groups.

Example:

SELECT
EmployeeID,
Salary,
NTILE(4)
OVER(ORDER BY Salary DESC)
AS Quartile
FROM HumanResources.Employee;

Employees are divided into four salary quartiles.


Offset Functions

Offset functions compare one row to another.

Common functions include:

  • LAG()
  • LEAD()

LAG()

Returns a value from a previous row.

Example:

SELECT
OrderDate,
SalesAmount,
LAG(SalesAmount)
OVER(ORDER BY OrderDate)
AS PreviousDaySales
FROM Sales.DailySales;

LEAD()

Returns a value from a following row.

Example:

SELECT
OrderDate,
SalesAmount,
LEAD(SalesAmount)
OVER(ORDER BY OrderDate)
AS NextDaySales
FROM Sales.DailySales;

FIRST_VALUE()

Returns the first value in the window.

Example:

SELECT
EmployeeID,
Salary,
FIRST_VALUE(Salary)
OVER(ORDER BY Salary DESC)
AS HighestSalary
FROM HumanResources.Employee;

LAST_VALUE()

Returns the last value within the current window frame.

Example:

SELECT
EmployeeID,
Salary,
LAST_VALUE(Salary)
OVER
(
ORDER BY Salary
ROWS BETWEEN UNBOUNDED PRECEDING
AND UNBOUNDED FOLLOWING
)
AS HighestSalary
FROM HumanResources.Employee;

Because LAST_VALUE() respects the current window frame, explicitly specifying the frame is often necessary to obtain the expected result.


Window Frames

Window frames define which rows participate in a calculation.

Common options include:

  • CURRENT ROW
  • UNBOUNDED PRECEDING
  • UNBOUNDED FOLLOWING
  • n PRECEDING
  • n FOLLOWING

Example:

ROWS BETWEEN 5 PRECEDING
AND CURRENT ROW

This frame includes the current row plus the previous five rows.


ROWS vs. RANGE

ROWSRANGE
Uses physical row positionsUses logical value ranges
Predictable row countsMay include multiple tied rows
Often preferred for running totalsUseful for value-based calculations

For most reporting scenarios, ROWS provides more predictable behavior.


Combining PARTITION BY and ORDER BY

Example:

SELECT
DepartmentID,
EmployeeID,
Salary,
ROW_NUMBER()
OVER
(
PARTITION BY DepartmentID
ORDER BY Salary DESC
)
AS DepartmentRank
FROM HumanResources.Employee;

Ranking restarts for each department.


Practical Business Uses

Window functions are commonly used for:

  • Sales rankings
  • Running totals
  • Financial reporting
  • Trend analysis
  • Customer segmentation
  • Inventory analysis
  • Employee rankings
  • Time-series analysis
  • Rolling averages
  • Year-over-year comparisons

Performance Considerations

Window functions can require sorting operations.

Performance depends on:

  • Index design
  • Partition size
  • Number of rows
  • ORDER BY columns
  • Available memory

To improve performance:

  • Index columns used in PARTITION BY and ORDER BY.
  • Avoid unnecessary sorting.
  • Limit returned rows when appropriate.
  • Review execution plans.
  • Consider filtered datasets before applying window functions.

AI-Enabled Database Scenarios

Window functions are valuable for preparing data used by AI applications.

Examples include:

  • Ranking search results before intelligent retrieval
  • Identifying the latest customer interactions for Retrieval-Augmented Generation (RAG)
  • Calculating rolling metrics for machine learning features
  • Detecting trends in IoT sensor data
  • Selecting the top-N records for embedding generation
  • Comparing current values with previous observations using LAG() and LEAD()
  • Preparing time-series datasets for AI forecasting models

These capabilities help organize and enrich data before it is consumed by AI pipelines.


Best Practices

  • Always specify an appropriate ORDER BY clause when required.
  • Use PARTITION BY only when logical grouping is needed.
  • Understand the differences among ranking functions.
  • Specify window frames explicitly for running totals and functions such as LAST_VALUE().
  • Create indexes on frequently partitioned or sorted columns.
  • Test performance with production-sized datasets.
  • Avoid unnecessary nested window calculations.
  • Review execution plans for expensive sorts.

Common Exam Tips

For the DP-800 exam, remember these key points:

  • Window functions require the OVER clause.
  • PARTITION BY divides rows into logical groups.
  • ORDER BY defines the order within each window.
  • Window functions preserve individual rows.
  • ROW_NUMBER() always returns unique sequential numbers.
  • RANK() allows gaps after ties.
  • DENSE_RANK() does not leave gaps after ties.
  • LAG() retrieves values from previous rows.
  • LEAD() retrieves values from subsequent rows.
  • Running totals commonly use SUM() with ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.

Practice Exam Questions

Question 1

Which clause is required for every SQL Server window function?

A. GROUP BY

B. HAVING

C. OVER

D. PARTITION

Answer: C

Explanation: Every window function must include the OVER clause, which defines the window over which the calculation is performed.


Question 2

What is the primary advantage of a window function over a traditional aggregate function?

A. It always executes faster.

B. It preserves individual rows while performing calculations across related rows.

C. It automatically creates indexes.

D. It eliminates the need for sorting.

Answer: B

Explanation: Unlike aggregate functions with GROUP BY, window functions return calculations while preserving each row in the result set.


Question 3

Which window function assigns a unique sequential number to every row, even when duplicate values exist?

A. RANK()

B. DENSE_RANK()

C. NTILE()

D. ROW_NUMBER()

Answer: D

Explanation: ROW_NUMBER() always assigns unique sequential numbers, regardless of duplicate values.


Question 4

Which ranking function assigns the same rank to tied rows without leaving gaps in subsequent rankings?

A. ROW_NUMBER()

B. NTILE()

C. DENSE_RANK()

D. RANK()

Answer: C

Explanation: DENSE_RANK() assigns the same rank to tied rows and continues with the next consecutive rank without gaps.


Question 5

What is the purpose of the PARTITION BY clause?

A. To permanently divide a table into partitions.

B. To group rows into logical partitions for window function calculations.

C. To sort the final result set.

D. To filter rows before processing.

Answer: B

Explanation: PARTITION BY creates logical groups within the result set so calculations are performed independently for each partition.


Question 6

Which function returns the value from the previous row within the defined window?

A. LEAD()

B. FIRST_VALUE()

C. LAST_VALUE()

D. LAG()

Answer: D

Explanation: LAG() retrieves a value from a preceding row within the same window.


Question 7

A developer needs to calculate a running total ordered by transaction date. Which feature is most appropriate?

A. SUM() with OVER and a window frame

B. GROUP BY

C. DISTINCT

D. UNION

Answer: A

Explanation: Running totals are typically calculated using SUM() with the OVER clause and a window frame such as ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.


Question 8

What is the default behavior of RANK() when multiple rows have the same value?

A. Each tied row receives a different rank.

B. Tied rows receive the same rank, and the next rank contains a gap.

C. Tied rows are ignored.

D. Tied rows receive sequential ranks without gaps.

Answer: B

Explanation: RANK() assigns identical ranks to tied rows and skips the next ranking number accordingly.


Question 9

Which statement about window frames is correct?

A. They are used only with ranking functions.

B. They define which rows participate in a window calculation.

C. They permanently partition a table.

D. They replace the ORDER BY clause.

Answer: B

Explanation: Window frames specify the subset of rows within the window that contribute to the calculation, making them especially useful for running totals and moving averages.


Question 10

How are window functions commonly used in AI-enabled database solutions?

A. They directly generate embeddings from text.

B. They replace vector indexes.

C. They prepare and enrich data by calculating rankings, rolling metrics, and historical comparisons before it is consumed by AI models, intelligent search, or Retrieval-Augmented Generation (RAG) pipelines.

D. They eliminate the need for data preprocessing.

Answer: C

Explanation: Window functions help organize and enrich datasets by calculating analytical metrics, rankings, and trends that serve as valuable inputs to AI workflows and machine learning processes.


Go to the DP-800 Exam Prep Hub main page

Write Common Table Expressions (CTEs) (DP-800 Exam Prep)

This post is a part of the DP-800: Developing AI-Enabled Database Solutions Exam Prep Hub.
This topic falls under these sections:
Design and develop database solutions (35–40%)
   --> Write advanced T-SQL code
      --> Write common table expressions (CTEs)


Note that there are 10 practice questions (with answers) at the end of each section to help you solidify your knowledge of the material. Also, there are 4 practice tests with 30 questions each available from the hub's main page below the exam topics section.

Introduction

A Common Table Expression (CTE) is a temporary, named result set that exists only for the duration of a single SQL statement. CTEs simplify complex queries by breaking them into logical, readable components. They can be referenced in SELECT, INSERT, UPDATE, DELETE, and MERGE statements and are particularly useful for hierarchical queries, recursive operations, and improving query readability.

Unlike temporary tables or table variables, CTEs are not physically stored in the database. They are defined using the WITH keyword and exist only during the execution of the immediately following statement.

For the DP-800: Developing AI-Enabled Database Solutions certification exam, you should understand:

  • What CTEs are
  • How to create and use CTEs
  • Nonrecursive CTEs
  • Recursive CTEs
  • Multiple CTEs
  • Using CTEs with DML statements
  • Recursive query patterns
  • Performance considerations
  • CTE limitations
  • Best practices
  • AI-enabled database scenarios

Understanding CTEs is important because they are commonly used in enterprise SQL development to organize complex logic, traverse hierarchical data, and prepare datasets for reporting and AI workloads.


What Is a Common Table Expression?

A Common Table Expression is a temporary named query defined immediately before another SQL statement.

General syntax:

WITH CTE_Name AS
(
SELECT ...
)
SELECT *
FROM CTE_Name;

The CTE is available only to the statement immediately following its definition.


Benefits of CTEs

CTEs offer several advantages:

  • Improve readability
  • Simplify complex queries
  • Replace deeply nested subqueries
  • Enable recursive queries
  • Make SQL easier to debug
  • Encourage modular query design
  • Improve maintainability
  • Support DML operations

Creating a Simple CTE

Example:

WITH HighValueOrders AS
(
SELECT
OrderID,
CustomerID,
TotalAmount
FROM Sales.Orders
WHERE TotalAmount > 5000
)
SELECT *
FROM HighValueOrders;

The CTE filters orders before the final query executes.


Referencing a CTE

A CTE behaves similarly to a temporary result set.

Example:

WITH CustomerTotals AS
(
SELECT
CustomerID,
SUM(TotalAmount) AS TotalSales
FROM Sales.Orders
GROUP BY CustomerID
)
SELECT *
FROM CustomerTotals
WHERE TotalSales > 10000;

CTEs and Query Readability

Without a CTE:

SELECT *
FROM
(
SELECT
CustomerID,
SUM(TotalAmount) AS TotalSales
FROM Sales.Orders
GROUP BY CustomerID
) AS SalesTotals;

Using a CTE often makes the query easier to understand, particularly when multiple steps are involved.


Multiple CTEs

Multiple CTEs can be defined within a single WITH clause.

Example:

WITH CustomerTotals AS
(
SELECT
CustomerID,
SUM(TotalAmount) AS TotalSales
FROM Sales.Orders
GROUP BY CustomerID
),
TopCustomers AS
(
SELECT *
FROM CustomerTotals
WHERE TotalSales > 10000
)
SELECT *
FROM TopCustomers;

Each CTE can reference earlier CTEs defined in the same WITH clause.


Recursive CTEs

A recursive CTE repeatedly references itself until a termination condition is met.

It consists of:

  • An anchor member
  • A recursive member

Example:

WITH Numbers AS
(
SELECT 1 AS Number
UNION ALL
SELECT Number + 1
FROM Numbers
WHERE Number < 10
)
SELECT *
FROM Numbers;

Result:

1
2
3
4
5
6
7
8
9
10

Recursive CTE Structure

A recursive CTE has two parts:

Anchor member

Returns the initial result.

SELECT 1 AS Number

Recursive member

References the CTE itself.

SELECT Number + 1
FROM Numbers
WHERE Number < 10

The recursion ends when no additional rows are returned.


Hierarchical Queries

Recursive CTEs are ideal for hierarchical data such as:

  • Organizational charts
  • Employee-manager relationships
  • Bill of materials
  • Folder structures
  • Product categories

Example:

WITH EmployeeHierarchy AS
(
SELECT
EmployeeID,
ManagerID,
EmployeeName
FROM HumanResources.Employee
WHERE ManagerID IS NULL
UNION ALL
SELECT
e.EmployeeID,
e.ManagerID,
e.EmployeeName
FROM HumanResources.Employee e
INNER JOIN EmployeeHierarchy h
ON e.ManagerID = h.EmployeeID
)
SELECT *
FROM EmployeeHierarchy;

Using MAXRECURSION

SQL Server limits recursion to 100 levels by default.

To override the limit:

OPTION (MAXRECURSION 500);

Unlimited recursion:

OPTION (MAXRECURSION 0);

Using unlimited recursion should be done cautiously to avoid infinite loops.


CTEs with INSERT

Example:

WITH LargeOrders AS
(
SELECT *
FROM Sales.Orders
WHERE TotalAmount > 10000
)
INSERT INTO Sales.ArchiveOrders
SELECT *
FROM LargeOrders;

CTEs with UPDATE

Example:

WITH CustomerDiscounts AS
(
SELECT
CustomerID,
Discount
FROM Sales.Customers
WHERE Discount < 0.05
)
UPDATE CustomerDiscounts
SET Discount = 0.05;

The CTE provides an updateable result set because it references a single base table without disqualifying constructs.


CTEs with DELETE

Example:

WITH OldOrders AS
(
SELECT *
FROM Sales.Orders
WHERE OrderDate < '2023-01-01'
)
DELETE
FROM OldOrders;

CTEs with MERGE

CTEs can simplify complex merge operations.

Example:

WITH UpdatedCustomers AS
(
SELECT *
FROM Sales.CustomerImport
)
MERGE Sales.Customers AS Target
USING UpdatedCustomers AS Source
ON Target.CustomerID = Source.CustomerID
WHEN MATCHED THEN
UPDATE
SET CustomerName = Source.CustomerName
WHEN NOT MATCHED THEN
INSERT (CustomerID, CustomerName)
VALUES (Source.CustomerID, Source.CustomerName);

CTEs vs. Subqueries

FeatureCTESubquery
ReadabilityHighModerate
Supports recursionYesNo
Reusable within statementYesLimited
Multiple logical stepsExcellentDifficult
Hierarchical queriesYesNo

CTEs vs. Temporary Tables

FeatureCTETemporary Table
Stored physicallyNoYes (tempdb)
Exists beyond one statementNoYes
Supports indexesNoYes
Good for complex multi-step processingSometimesYes
Good for readabilityExcellentModerate

CTEs vs. Table Variables

FeatureCTETable Variable
Temporary objectLogical onlyPhysical object in tempdb
Exists after statementNoYes
Supports indexesNo (directly)Limited (via constraints/indexes in newer versions)
Recursive queriesYesNo

Performance Considerations

Although CTEs improve readability, they do not automatically improve performance.

Consider the following:

  • CTEs are expanded into the execution plan by the optimizer rather than materialized by default.
  • Large CTEs referenced multiple times may be re-evaluated.
  • Recursive CTEs can become expensive for deep hierarchies.
  • Temporary tables may outperform CTEs for large intermediate result sets reused across multiple statements.
  • Proper indexing on underlying tables remains critical.

Always review the execution plan when optimizing complex queries.


CTE Limitations

Developers should understand these limitations:

  • Scope is limited to one statement.
  • Cannot be referenced by subsequent statements.
  • Cannot include an ORDER BY clause unless used with TOP, OFFSET/FETCH, or FOR XML.
  • Cannot create indexes on a CTE.
  • Recursive CTEs require a termination condition.
  • Excessive recursion can impact performance or lead to errors if recursion limits are exceeded.

AI-Enabled Database Scenarios

CTEs are frequently used in AI-enabled database solutions to prepare data before AI processing.

Examples include:

  • Cleaning and filtering text before embedding generation
  • Building hierarchical product catalogs for Retrieval-Augmented Generation (RAG)
  • Preparing conversation histories for prompt construction
  • Identifying duplicate records before vectorization
  • Aggregating customer interactions for AI analysis
  • Transforming datasets before intelligent search indexing
  • Organizing graph-like relationships that feed AI models

CTEs provide a readable way to express complex transformations commonly required before AI workflows.


Best Practices

  • Give CTEs meaningful names.
  • Use CTEs to simplify complex queries.
  • Prefer CTEs over deeply nested subqueries.
  • Use recursive CTEs only when recursion is required.
  • Always include a termination condition in recursive CTEs.
  • Test recursive queries with realistic datasets.
  • Review execution plans for large queries.
  • Consider temporary tables for large reusable intermediate results.
  • Keep CTE definitions focused on a single logical task.
  • Avoid excessive nesting of multiple CTEs.

Common Exam Tips

For the DP-800 exam, remember these key points:

  • CTEs begin with the WITH keyword.
  • A CTE exists only for the immediately following statement.
  • Recursive CTEs consist of an anchor member and a recursive member.
  • Recursive CTEs are commonly used for hierarchical data.
  • SQL Server limits recursion to 100 levels by default.
  • OPTION (MAXRECURSION n) changes the recursion limit.
  • CTEs can be used with SELECT, INSERT, UPDATE, DELETE, and MERGE.
  • CTEs are not stored as database objects.
  • CTEs improve readability but do not guarantee better performance.
  • Recursive CTEs must include a termination condition.

Practice Exam Questions

Question 1

Which keyword is used to define a Common Table Expression?

A. WITH

B. TEMP

C. DEFINE

D. AS

Answer: A

Explanation: Every Common Table Expression begins with the WITH keyword followed by the CTE name and query definition.


Question 2

How long does a Common Table Expression exist?

A. Until the database connection closes

B. Until the current transaction completes

C. Only for the execution of the immediately following SQL statement

D. Until it is explicitly dropped

Answer: C

Explanation: A CTE exists only for the single statement immediately following its definition.


Question 3

Which capability distinguishes a recursive CTE from a nonrecursive CTE?

A. It can reference itself.

B. It creates a permanent table.

C. It automatically creates indexes.

D. It stores intermediate results in tempdb.

Answer: A

Explanation: Recursive CTEs reference themselves to repeatedly process data until a termination condition is reached.


Question 4

Which type of data is most appropriate for a recursive CTE?

A. Monthly sales totals

B. Customer invoices

C. Product pricing

D. Organizational hierarchies

Answer: D

Explanation: Recursive CTEs are commonly used for hierarchical data such as organizational charts, bill of materials, and category trees.


Question 5

Which statement about recursive CTEs is correct?

A. They do not require an anchor member.

B. They require both an anchor member and a recursive member.

C. They can only return numeric data.

D. They cannot use UNION ALL.

Answer: B

Explanation: Every recursive CTE contains an anchor member that produces the initial rows and a recursive member that references the CTE itself.


Question 6

What is the default maximum recursion level in SQL Server?

A. 10

B. 50

C. 100

D. Unlimited

Answer: C

Explanation: SQL Server limits recursive CTE execution to 100 levels by default unless the MAXRECURSION query hint is specified.


Question 7

Which statement correctly describes CTE performance?

A. CTEs always execute faster than temporary tables.

B. CTEs are always materialized into temporary storage.

C. CTEs automatically create indexes.

D. CTEs primarily improve query readability, while performance depends on the execution plan and underlying data.

Answer: D

Explanation: CTEs improve readability and maintainability, but the query optimizer determines how they are executed. They do not inherently improve performance.


Question 8

Which DML operation can use a Common Table Expression?

A. SELECT only

B. SELECT and INSERT only

C. SELECT, INSERT, UPDATE, DELETE, and MERGE

D. UPDATE only

Answer: C

Explanation: CTEs can precede and be referenced by SELECT, INSERT, UPDATE, DELETE, and MERGE statements.


Question 9

When should a temporary table typically be preferred over a CTE?

A. When a readable single-statement query is needed

B. When recursion is required

C. When the intermediate result set must be reused across multiple statements or indexed

D. When querying hierarchical data

Answer: C

Explanation: Temporary tables persist beyond a single statement, can be indexed, and are often more efficient when intermediate results are reused multiple times.


Question 10

How are CTEs commonly used in AI-enabled database solutions?

A. They directly generate vector embeddings.

B. They replace vector indexes.

C. They eliminate the need for application logic.

D. They simplify complex data preparation tasks such as filtering, aggregating, and organizing data before embedding generation, intelligent search, or Retrieval-Augmented Generation (RAG) workflows.

Answer: D

Explanation: CTEs are commonly used to prepare and transform datasets before downstream AI processing, improving readability and maintainability of complex SQL used in AI-enabled database solutions.


Go to the DP-800 Exam Prep Hub main page

Create triggers (DP-800 Exam Prep)

This post is a part of the DP-800: Developing AI-Enabled Database Solutions Exam Prep Hub.
This topic falls under these sections:
Design and develop database solutions (35–40%)
   --> Implement programmability objects
      --> Create triggers


Note that there are 10 practice questions (with answers) at the end of each section to help you solidify your knowledge of the material. Also, there are 4 practice tests with 30 questions each available from the hub's main page below the exam topics section.

Introduction

Triggers are special types of stored procedures that automatically execute (or “fire”) in response to specific database events. Unlike stored procedures, which must be executed explicitly by a user or application, triggers are invoked automatically by SQL Server when certain Data Manipulation Language (DML), Data Definition Language (DDL), or logon events occur.

Triggers are commonly used to enforce complex business rules, maintain audit trails, synchronize related data, validate changes, and perform automated actions that occur whenever data or database objects are modified. While triggers are powerful, they should be used judiciously because they can add complexity and affect database performance if not carefully designed.

For the DP-800: Developing AI-Enabled Database Solutions certification exam, you should understand:

  • What triggers are
  • DML triggers
  • DDL triggers
  • AFTER and INSTEAD OF triggers
  • The inserted and deleted logical tables
  • Creating, altering, disabling, enabling, and dropping triggers
  • Nested and recursive triggers
  • Performance considerations
  • Best practices
  • AI-enabled database scenarios

Understanding triggers is important because they provide automatic execution of business logic while helping maintain data integrity and automate administrative tasks.


What Is a Trigger?

A trigger is a database object that automatically executes when a specified event occurs.

Triggers are associated with:

  • Tables
  • Views
  • Databases
  • SQL Server instances (for certain DDL and logon events)

Triggers cannot be executed directly using the EXEC statement.

Instead, SQL Server executes them automatically when the triggering event occurs.


Types of Triggers

SQL Server supports several types of triggers:

  • DML triggers
  • DDL triggers
  • Logon triggers

The DP-800 exam primarily focuses on DML and DDL triggers.


DML Triggers

Data Manipulation Language (DML) triggers fire when data is modified.

They respond to:

  • INSERT
  • UPDATE
  • DELETE

Typical uses include:

  • Auditing data changes
  • Enforcing business rules
  • Validating updates
  • Synchronizing tables
  • Recording historical information

AFTER Triggers

An AFTER trigger executes only after the triggering statement completes successfully.

Example:

CREATE TRIGGER trgCustomerAudit
ON Sales.Customers
AFTER INSERT
AS
BEGIN
INSERT INTO Sales.CustomerAudit
(
CustomerID,
AuditDate
)
SELECT
CustomerID,
GETDATE()
FROM inserted;
END;

The trigger records newly inserted customers after the insert operation succeeds.


INSTEAD OF Triggers

An INSTEAD OF trigger executes in place of the triggering action.

Example:

CREATE TRIGGER trgPreventDelete
ON Sales.Customers
INSTEAD OF DELETE
AS
BEGIN
PRINT 'Deleting customers is not permitted.';
END;

The DELETE statement never executes because the trigger replaces it.

INSTEAD OF triggers are commonly used on:

  • Views
  • Complex update scenarios
  • Custom validation logic

DDL Triggers

DDL triggers respond to schema changes.

Common events include:

  • CREATE TABLE
  • ALTER TABLE
  • DROP TABLE
  • CREATE PROCEDURE
  • ALTER PROCEDURE
  • DROP PROCEDURE

Example:

CREATE TRIGGER trgAuditDDL
ON DATABASE
FOR CREATE_TABLE
AS
BEGIN
PRINT 'A table was created.';
END;

DDL triggers help monitor or prevent unauthorized schema modifications.


Logon Triggers

Logon triggers execute when a user establishes a SQL Server session.

Typical uses include:

  • Restricting connections
  • Recording login activity
  • Enforcing security policies

Logon triggers are created at the server level and are not supported in Azure SQL Database.


The inserted Logical Table

Whenever rows are inserted or updated, SQL Server creates a temporary logical table named inserted.

It contains the new version of affected rows.

Example:

SELECT *
FROM inserted;

The inserted table exists only during trigger execution.


The deleted Logical Table

Whenever rows are deleted or updated, SQL Server creates a logical table named deleted.

It contains the original version of affected rows.

Example:

SELECT *
FROM deleted;

For UPDATE operations:

  • deleted contains old values.
  • inserted contains new values.

Auditing Changes

Triggers are frequently used to create audit trails.

Example:

CREATE TRIGGER trgAuditSalary
ON HumanResources.Employees
AFTER UPDATE
AS
BEGIN
INSERT INTO HumanResources.SalaryAudit
(
EmployeeID,
OldSalary,
NewSalary,
ChangeDate
)
SELECT
d.EmployeeID,
d.Salary,
i.Salary,
GETDATE()
FROM deleted d
INNER JOIN inserted i
ON d.EmployeeID = i.EmployeeID;
END;

This trigger records salary changes for auditing purposes.


Enforcing Business Rules

Triggers can prevent invalid operations.

Example:

CREATE TRIGGER trgNoNegativeInventory
ON Inventory.Products
AFTER UPDATE
AS
BEGIN
IF EXISTS
(
SELECT *
FROM inserted
WHERE Quantity < 0
)
BEGIN
RAISERROR
(
'Inventory cannot be negative.',
16,
1
);
ROLLBACK TRANSACTION;
END;
END;

The trigger rolls back the transaction if inventory becomes negative.


Multi-Row Operations

Triggers execute once per SQL statement, not once per affected row.

For example:

UPDATE Sales.Customers
SET City = 'Miami';

If 10,000 rows are updated, the trigger executes only once.

The inserted and deleted tables contain all affected rows.

Developers should always write triggers using set-based logic, not assumptions that only one row is affected.


Nested Triggers

A trigger can cause another trigger to fire.

Example:

  • Trigger A updates Table B.
  • Table B has Trigger B.
  • Trigger B executes automatically.

This behavior is called nested triggers.

SQL Server supports nested triggers up to a configurable limit.


Recursive Triggers

A recursive trigger fires itself either directly or indirectly.

Example:

  • Trigger updates its own table.
  • That update causes the same trigger to execute again.

Recursive triggers are disabled by default in many environments and should be used with caution to avoid infinite loops.


Enabling and Disabling Triggers

Disable a trigger:

DISABLE TRIGGER trgCustomerAudit
ON Sales.Customers;

Enable it:

ENABLE TRIGGER trgCustomerAudit
ON Sales.Customers;

Disabling a trigger preserves its definition while preventing it from firing.


Modifying a Trigger

Use ALTER TRIGGER.

Example:

ALTER TRIGGER trgCustomerAudit
ON Sales.Customers
AFTER INSERT
AS
BEGIN
PRINT 'Customer inserted.';
END;

Deleting a Trigger

Use:

DROP TRIGGER trgCustomerAudit;

Viewing Trigger Definitions

Developers can inspect a trigger using:

sp_helptext 'trgCustomerAudit';

Or:

SELECT OBJECT_DEFINITION
(
OBJECT_ID('trgCustomerAudit')
);

Triggers vs. Stored Procedures

FeatureTriggerStored Procedure
Executes automaticallyYesNo
Invoked by EXECNoYes
Responds to database eventsYesNo
Accepts parametersNoYes
Returns result setsNot intended for callersYes

Triggers vs. Constraints

FeatureTriggerConstraint
Enforces simple rulesPossibleYes
Enforces complex business logicYesLimited
Can reference multiple tablesYesLimited
Executes automaticallyYesYes

Constraints should generally be preferred for simple validation rules because they are simpler and often more efficient.


Performance Considerations

Triggers execute within the same transaction as the triggering statement.

Poorly designed triggers can:

  • Increase transaction duration
  • Increase locking
  • Reduce concurrency
  • Consume additional CPU resources
  • Introduce blocking
  • Increase deadlock risk

Best practices include:

  • Keep trigger logic simple.
  • Use set-based operations.
  • Avoid unnecessary queries.
  • Avoid long-running operations.
  • Minimize external dependencies.
  • Do not assume only one row is affected.

Security Considerations

Triggers can:

  • Audit sensitive changes
  • Prevent unauthorized updates
  • Enforce compliance policies
  • Record administrative activity
  • Restrict schema modifications using DDL triggers

Proper permissions should be applied because trigger code executes in the database context.


AI-Enabled Database Scenarios

Triggers can support AI-enabled database solutions by automating actions whenever data changes.

Examples include:

  • Recording changes that require new embeddings to be generated
  • Logging modifications to AI training datasets
  • Flagging rows for downstream vectorization processes
  • Updating AI metadata tables after inserts or updates
  • Capturing prompt history for auditing
  • Initiating workflows that prepare data for intelligent search or Retrieval-Augmented Generation (RAG)

Although triggers cannot directly invoke external AI services, they can populate work queues or status tables that downstream applications or services process.


Best Practices

  • Prefer constraints for simple validation.
  • Use triggers only when automatic behavior is required.
  • Write triggers using set-based logic.
  • Minimize execution time.
  • Avoid recursive logic unless absolutely necessary.
  • Test triggers with multi-row operations.
  • Document business rules implemented by triggers.
  • Avoid unnecessary nested trigger chains.
  • Monitor trigger performance.
  • Audit only the information that is required.

Common Exam Tips

For the DP-800 exam, remember these key points:

  • Triggers execute automatically in response to events.
  • DML triggers respond to INSERT, UPDATE, and DELETE statements.
  • DDL triggers respond to schema changes.
  • AFTER triggers execute after the triggering statement completes successfully.
  • INSTEAD OF triggers replace the triggering action.
  • inserted contains new row values.
  • deleted contains original row values.
  • Triggers fire once per statement, not once per row.
  • Use ALTER TRIGGER to modify a trigger.
  • Use DISABLE TRIGGER, ENABLE TRIGGER, and DROP TRIGGER to manage trigger lifecycle.

Practice Exam Questions

Question 1

A developer wants database logic to execute automatically whenever rows are inserted into a table. Which database object should be used?

A. Stored procedure

B. Trigger

C. View

D. Scalar function

Answer: B

Explanation: Triggers automatically execute in response to specified database events such as INSERT, UPDATE, or DELETE operations.


Question 2

Which type of trigger executes only after the triggering statement has completed successfully?

A. BEFORE trigger

B. INSTEAD OF trigger

C. AFTER trigger

D. LOGON trigger

Answer: C

Explanation: An AFTER trigger fires only after the triggering DML statement has completed successfully and any associated constraints have been processed.


Question 3

During an UPDATE operation, which logical table contains the original values of the modified rows?

A. inserted

B. updated

C. original

D. deleted

Answer: D

Explanation: During an UPDATE, the deleted logical table contains the original row values, while the inserted table contains the new values.


Question 4

Which trigger type replaces the original INSERT, UPDATE, or DELETE operation?

A. AFTER trigger

B. DDL trigger

C. INSTEAD OF trigger

D. Recursive trigger

Answer: C

Explanation: An INSTEAD OF trigger executes instead of the triggering statement, allowing custom processing or validation.


Question 5

A trigger is written assuming that only one row is updated at a time. Why is this a problem?

A. SQL Server executes one trigger for every row.

B. Triggers always execute asynchronously.

C. Triggers execute once per SQL statement and may process many affected rows.

D. UPDATE statements cannot affect multiple rows.

Answer: C

Explanation: SQL Server fires DML triggers once per statement, so developers must use set-based logic to correctly process all affected rows.


Question 6

Which statement disables a trigger while preserving its definition?

A. REMOVE TRIGGER

B. DROP TRIGGER

C. ALTER TRIGGER

D. DISABLE TRIGGER

Answer: D

Explanation: DISABLE TRIGGER prevents a trigger from firing without deleting it, allowing it to be re-enabled later.


Question 7

Which statement best describes a DDL trigger?

A. It responds to changes in table data.

B. It responds to schema modification events such as CREATE, ALTER, or DROP statements.

C. It executes only during user logins.

D. It replaces the execution of stored procedures.

Answer: B

Explanation: DDL triggers respond to schema-related events, making them useful for auditing or preventing structural database changes.


Question 8

Which object is generally preferred for enforcing a simple rule such as ensuring a value is greater than zero?

A. AFTER trigger

B. CHECK constraint

C. DDL trigger

D. Stored procedure

Answer: B

Explanation: CHECK constraints are simpler, easier to maintain, and generally more efficient than triggers for straightforward validation rules.


Question 9

Which statement correctly describes nested triggers?

A. They occur only with DDL triggers.

B. They allow a trigger to execute dynamic SQL.

C. They occur when one trigger causes another trigger to fire.

D. They are required whenever inserted and deleted tables are referenced.

Answer: C

Explanation: Nested triggers occur when the actions performed by one trigger cause another trigger to execute.


Question 10

How can triggers support AI-enabled database solutions?

A. They automatically generate embeddings by calling AI models directly.

B. They replace vector indexes.

C. They eliminate the need for application code.

D. They automatically detect data changes and populate work queues, audit tables, or status records that downstream AI processes use to generate embeddings, update indexes, or prepare RAG data.

Answer: D

Explanation: Triggers are well suited for detecting data changes and initiating downstream workflows by recording changes or updating processing queues. External applications or services can then consume these queues to perform AI-related tasks such as embedding generation or intelligent indexing.


Go to the DP-800 Exam Prep Hub main page

Create stored procedures (DP-800 Exam Prep)

This post is a part of the DP-800: Developing AI-Enabled Database Solutions Exam Prep Hub.
This topic falls under these sections:
Design and develop database solutions (35–40%)
   --> Implement programmability objects
      --> Create stored procedures


Note that there are 10 practice questions (with answers) at the end of each section to help you solidify your knowledge of the material. Also, there are 4 practice tests with 30 questions each available from the hub's main page below the exam topics section.

Introduction

Stored procedures are one of the most powerful programmability objects available in SQL Server and Azure SQL Database. A stored procedure is a precompiled collection of one or more Transact-SQL (T-SQL) statements that perform a specific task. Stored procedures allow developers to encapsulate business logic, automate repetitive database operations, improve application security, and optimize performance.

Stored procedures are widely used in enterprise applications for Create, Read, Update, Delete (CRUD) operations, reporting, data validation, data processing, ETL workflows, auditing, and integrating applications with databases. They are also valuable in AI-enabled database solutions where they can orchestrate data preparation, invoke AI-related operations, and manage workflows that interact with vector data, embeddings, and Retrieval-Augmented Generation (RAG) pipelines.

For the DP-800: Developing AI-Enabled Database Solutions certification exam, you should understand:

  • What stored procedures are
  • How to create, alter, execute, and delete stored procedures
  • Input and output parameters
  • Returning result sets and status codes
  • Error handling
  • Transactions
  • Dynamic SQL
  • Temporary objects
  • Security considerations
  • Performance optimization
  • Best practices

Understanding stored procedures is essential because they are one of the primary methods for implementing reusable business logic in SQL Server.


What Is a Stored Procedure?

A stored procedure is a named database object that contains one or more SQL statements that execute as a unit.

Unlike functions, stored procedures:

  • Can return zero, one, or multiple result sets
  • Can modify database data
  • Can execute DDL and DML statements
  • Can contain transactions
  • Can execute dynamic SQL
  • Can include error handling
  • Can call other stored procedures

Stored procedures are stored within the database and executed on demand.


Benefits of Stored Procedures

Stored procedures provide numerous advantages:

  • Encapsulate business logic
  • Reduce duplicate SQL code
  • Improve security
  • Simplify application development
  • Improve maintainability
  • Reduce network traffic
  • Support transaction management
  • Improve performance through execution plan reuse
  • Simplify administrative operations

Creating a Stored Procedure

Basic syntax:

CREATE PROCEDURE dbo.uspGetCustomers
AS
BEGIN
SELECT
CustomerID,
CustomerName,
City
FROM Sales.Customers;
END;

Execute the procedure:

EXEC dbo.uspGetCustomers;

or

EXECUTE dbo.uspGetCustomers;

Creating a Stored Procedure with Parameters

Most stored procedures accept one or more parameters.

Example:

CREATE PROCEDURE dbo.uspGetCustomerOrders
(
@CustomerID INT
)
AS
BEGIN
SELECT
OrderID,
OrderDate,
TotalAmount
FROM Sales.Orders
WHERE CustomerID = @CustomerID;
END;

Execute:

EXEC dbo.uspGetCustomerOrders
@CustomerID = 100;

Parameters make procedures reusable across many scenarios.


Using Multiple Parameters

Example:

CREATE PROCEDURE dbo.uspOrdersByDate
(
@StartDate DATE,
@EndDate DATE
)
AS
BEGIN
SELECT *
FROM Sales.Orders
WHERE OrderDate BETWEEN @StartDate AND @EndDate;
END;

Optional Parameters

Parameters may have default values.

Example:

CREATE PROCEDURE dbo.uspGetOrders
(
@Status VARCHAR(20) = 'Open'
)
AS
BEGIN
SELECT *
FROM Sales.Orders
WHERE Status = @Status;
END;

Now the procedure can be executed with or without specifying the parameter.


Output Parameters

Stored procedures can return values through output parameters.

Example:

CREATE PROCEDURE dbo.uspGetOrderCount
(
@CustomerID INT,
@OrderCount INT OUTPUT
)
AS
BEGIN
SELECT
@OrderCount = COUNT(*)
FROM Sales.Orders
WHERE CustomerID = @CustomerID;
END;

Execution:

DECLARE @Count INT;
EXEC dbo.uspGetOrderCount
@CustomerID = 100,
@OrderCount = @Count OUTPUT;
SELECT @Count;

Returning Status Codes

Stored procedures may return an integer status code.

Example:

CREATE PROCEDURE dbo.uspExample
AS
BEGIN
RETURN 0;
END;

Execution:

DECLARE @ReturnCode INT;
EXEC @ReturnCode = dbo.uspExample;
SELECT @ReturnCode;

A return code is commonly used to indicate success or failure.


Returning Result Sets

Stored procedures frequently return result sets.

Example:

CREATE PROCEDURE dbo.uspTopCustomers
AS
BEGIN
SELECT TOP (10)
CustomerName,
TotalSales
FROM Sales.CustomerTotals
ORDER BY TotalSales DESC;
END;

Applications can consume the returned rows directly.


Data Modification

Stored procedures commonly perform INSERT, UPDATE, DELETE, and MERGE operations.

Example:

CREATE PROCEDURE dbo.uspInsertCustomer
(
@CustomerName NVARCHAR(100),
@City NVARCHAR(50)
)
AS
BEGIN
INSERT INTO Sales.Customers
(
CustomerName,
City
)
VALUES
(
@CustomerName,
@City
);
END;

Using Transactions

Stored procedures frequently include explicit transactions.

Example:

CREATE PROCEDURE dbo.uspTransferFunds
AS
BEGIN
BEGIN TRANSACTION;
-- Debit account
-- Credit account
COMMIT TRANSACTION;
END;

Transactions ensure that all related operations either succeed together or fail together.


Error Handling

SQL Server supports structured error handling with TRY...CATCH.

Example:

CREATE PROCEDURE dbo.uspExample
AS
BEGIN
BEGIN TRY
SELECT 1/0;
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE();
END CATCH
END;

Functions cannot use TRY...CATCH, making this an important distinction between stored procedures and functions.


Dynamic SQL

Stored procedures can execute dynamic SQL.

Example:

CREATE PROCEDURE dbo.uspDynamicSearch
(
@TableName SYSNAME
)
AS
BEGIN
DECLARE @SQL NVARCHAR(MAX);
SET @SQL =
N'SELECT * FROM ' + QUOTENAME(@TableName);
EXEC sp_executesql @SQL;
END;

Using sp_executesql is generally preferred over EXEC() because it supports parameterization and helps reduce SQL injection risks.


Temporary Tables

Stored procedures often use temporary tables.

Example:

CREATE PROCEDURE dbo.uspSalesReport
AS
BEGIN
CREATE TABLE #Sales
(
OrderID INT,
Total MONEY
);
INSERT INTO #Sales
SELECT
OrderID,
TotalAmount
FROM Sales.Orders;
SELECT *
FROM #Sales;
END;

Temporary tables exist only during the session or procedure execution.


Table Variables

Stored procedures may also use table variables.

Example:

DECLARE @Orders TABLE
(
OrderID INT,
Total MONEY
);

Table variables are useful for storing smaller intermediate result sets.


Modifying a Stored Procedure

Use ALTER PROCEDURE.

Example:

ALTER PROCEDURE dbo.uspGetCustomers
AS
BEGIN
SELECT
CustomerID,
CustomerName,
City,
Country
FROM Sales.Customers;
END;

Deleting a Stored Procedure

Use:

DROP PROCEDURE dbo.uspGetCustomers;

Viewing a Stored Procedure Definition

Developers can inspect a procedure using:

sp_helptext 'dbo.uspGetCustomers';

or

SELECT OBJECT_DEFINITION
(
OBJECT_ID('dbo.uspGetCustomers')
);

Stored Procedures vs. Functions

FeatureStored ProcedureFunction
Returns a tableMay return result setsTable-valued functions only
Returns a scalar valueVia OUTPUT or RETURNScalar functions return one value
Used in SELECTNoYes (functions)
Can modify dataYesLimited; functions cannot modify permanent user tables
Supports transactionsYesNo
Supports TRY…CATCHYesNo
Supports dynamic SQLYesNo

Stored Procedures vs. Views

FeatureStored ProcedureView
Accepts parametersYesNo
Modifies dataYesNo (except through updatable views under certain conditions)
Contains procedural logicYesNo
Executes transactionsYesNo

Security Benefits

Stored procedures improve security by:

  • Granting EXECUTE permission instead of direct table access
  • Encapsulating sensitive business rules
  • Reducing the application’s need for elevated privileges
  • Supporting ownership chaining in many scenarios
  • Helping minimize SQL injection risks through parameterized queries

Performance Considerations

Stored procedures often improve performance because:

  • Execution plans can be reused.
  • SQL is compiled and optimized by the query optimizer.
  • Network traffic is reduced because only the procedure call is transmitted.
  • Business logic executes close to the data.

However, developers should also understand parameter sniffing, where SQL Server creates an execution plan based on the parameter values supplied during compilation. In some cases, this plan may not be optimal for different parameter values. Techniques such as OPTION (RECOMPILE), OPTIMIZE FOR, or carefully designed query patterns may help address parameter-sensitive performance issues.


AI-Enabled Database Scenarios

Stored procedures play an important role in AI-enabled database solutions.

Examples include:

  • Preparing data before generating embeddings
  • Coordinating vector insert and update operations
  • Executing intelligent search workflows
  • Managing Retrieval-Augmented Generation (RAG) data preparation
  • Orchestrating multi-step AI pipelines
  • Logging AI requests and responses
  • Performing batch updates for AI-generated content
  • Calling Azure services from application workflows that interact with the database

Stored procedures provide a reliable way to centralize business logic that supports AI applications.


Best Practices

  • Use descriptive names such as uspGetCustomerOrders.
  • Keep procedures focused on a single responsibility.
  • Use parameterized queries whenever possible.
  • Prefer sp_executesql over concatenated dynamic SQL.
  • Include proper error handling with TRY...CATCH.
  • Use transactions only when necessary and keep them as short as possible.
  • Return only the data that callers require.
  • Document business logic clearly.
  • Test procedures with realistic workloads.
  • Monitor execution plans and optimize when needed.

Common Exam Tips

For the DP-800 exam, remember these key points:

  • Stored procedures encapsulate reusable business logic.
  • Procedures can accept input parameters and output parameters.
  • They can return one or more result sets.
  • They support transactions, dynamic SQL, and error handling.
  • CREATE PROCEDURE creates a procedure.
  • ALTER PROCEDURE modifies an existing procedure.
  • DROP PROCEDURE removes a procedure.
  • Stored procedures can modify database data.
  • Procedures cannot be referenced directly in the FROM clause like table-valued functions.
  • Stored procedures are commonly used for CRUD operations, reporting, ETL, and AI workflow orchestration.

Practice Exam Questions

Question 1

A developer needs a reusable database object that can contain multiple SQL statements, modify data, and execute transactions. Which object should be created?

A. View

B. Scalar function

C. Stored procedure

D. Table-valued function

Answer: C

Explanation: Stored procedures are designed to encapsulate reusable business logic, modify data, execute transactions, and perform procedural operations.


Question 2

Which statement is used to execute an existing stored procedure?

A. EXEC

B. RUN

C. CALLPROC

D. EXECUTEQUERY

Answer: A

Explanation: SQL Server executes stored procedures using EXEC or its equivalent keyword EXECUTE.


Question 3

A stored procedure needs to return a calculated value to the calling application without including it in a result set. Which feature should be used?

A. CHECK constraint

B. OUTPUT parameter

C. DEFAULT constraint

D. Computed column

Answer: B

Explanation: OUTPUT parameters allow a stored procedure to return one or more values directly to the caller in addition to any result sets.


Question 4

Which capability is supported by stored procedures but not by user-defined functions?

A. Accepting parameters

B. Returning values

C. Executing TRY...CATCH error handling

D. Being stored in the database

Answer: C

Explanation: Stored procedures support structured error handling with TRY...CATCH, whereas user-defined functions do not.


Question 5

A developer needs to generate SQL statements dynamically while minimizing SQL injection risks. Which approach is recommended?

A. Use concatenated SQL with EXEC()

B. Store SQL in a view

C. Use a scalar function

D. Use sp_executesql with parameters

Answer: D

Explanation: sp_executesql supports parameterized dynamic SQL, improving security and enabling better plan reuse.


Question 6

Which statement modifies an existing stored procedure?

A. MODIFY PROCEDURE

B. ALTER PROCEDURE

C. UPDATE PROCEDURE

D. CHANGE PROCEDURE

Answer: B

Explanation: ALTER PROCEDURE changes the definition of an existing stored procedure without dropping and recreating it.


Question 7

Which statement about stored procedures is correct?

A. They can be referenced directly in the FROM clause of a SELECT statement.

B. They cannot accept parameters.

C. They can contain transactions and modify database data.

D. They always return exactly one scalar value.

Answer: C

Explanation: Stored procedures support transactions, data modification, and complex procedural logic. They cannot be queried directly in the FROM clause.


Question 8

What is parameter sniffing?

A. Encrypting stored procedure parameters.

B. Automatically validating parameter data types.

C. Caching parameter values for auditing.

D. Creating an execution plan based on parameter values supplied during compilation, which may not always be optimal for future executions.

Answer: D

Explanation: Parameter sniffing occurs when SQL Server optimizes a query using the initial parameter values, which can lead to less efficient plans for different parameter values.


Question 9

Which security benefit is commonly associated with stored procedures?

A. They automatically encrypt all stored data.

B. They eliminate the need for authentication.

C. They prevent all SQL injection attacks regardless of implementation.

D. They allow users to receive EXECUTE permission without requiring direct access to underlying tables.

Answer: D

Explanation: Granting EXECUTE permission on stored procedures helps restrict direct access to tables while encapsulating business logic and access patterns.


Question 10

How are stored procedures commonly used in AI-enabled database solutions?

A. They automatically generate embeddings without application logic.

B. They replace vector indexes.

C. They orchestrate reusable workflows such as preparing data, managing vector operations, logging AI activity, and supporting Retrieval-Augmented Generation (RAG) pipelines.

D. They eliminate the need for application code.

Answer: C

Explanation: Stored procedures centralize business logic and coordinate multi-step operations, making them well suited for AI-related workflows that prepare data, manage vectors, and support RAG processes.


Go to the DP-800 Exam Prep Hub main page

Create table-valued functions (DP-800 Exam Prep)

This post is a part of the DP-800: Developing AI-Enabled Database Solutions Exam Prep Hub.
This topic falls under these sections:
Design and develop database solutions (35–40%)
   --> Implement programmability objects
      --> Create table-valued functions


Note that there are 10 practice questions (with answers) at the end of each section to help you solidify your knowledge of the material. Also, there are 4 practice tests with 30 questions each available from the hub's main page below the exam topics section.

Introduction

Table-valued functions (TVFs) are user-defined database objects in SQL Server and Azure SQL Database that return a table rather than a single scalar value. They enable developers to encapsulate reusable query logic that can be invoked like a table within SQL statements.

Unlike scalar functions, which return a single value, table-valued functions return a result set that can be filtered, joined, aggregated, and queried just like a regular table or view. They are widely used to simplify complex queries, implement reusable business logic, parameterize data retrieval, and support reporting, analytics, and AI-enabled database solutions.

For the DP-800: Developing AI-Enabled Database Solutions certification exam, you should understand:

  • What table-valued functions are
  • Inline table-valued functions (iTVFs)
  • Multi-statement table-valued functions (MSTVFs)
  • How to create, modify, and delete TVFs
  • Parameters and return tables
  • Performance differences between iTVFs and MSTVFs
  • Appropriate use cases
  • Best practices

Understanding TVFs is important because they provide reusable, parameterized query logic while integrating seamlessly into T-SQL queries.


What Is a Table-Valued Function?

A table-valued function is a user-defined function that returns a table.

Unlike stored procedures, TVFs can be referenced directly in the FROM clause of a query.

Example:

SELECT *
FROM dbo.fnActiveCustomers();

The returned table behaves like any other table expression.


Benefits of Table-Valed Functions

TVFs provide numerous advantages:

  • Encapsulate reusable query logic
  • Accept input parameters
  • Return structured result sets
  • Simplify complex SQL
  • Improve maintainability
  • Support modular application design
  • Can be joined with other tables
  • Can be filtered and aggregated

Types of Table-Valued Functions

SQL Server supports two types:

  1. Inline Table-Valued Functions (iTVFs)
  2. Multi-Statement Table-Valued Functions (MSTVFs)

Understanding the differences is important for the DP-800 exam.


Inline Table-Valued Functions (iTVFs)

An inline TVF consists of a single SELECT statement.

General syntax:

CREATE FUNCTION dbo.FunctionName
(
@Parameter DataType
)
RETURNS TABLE
AS
RETURN
(
SELECT ...
);

Example:

CREATE FUNCTION dbo.fnOrdersByCustomer
(
@CustomerID INT
)
RETURNS TABLE
AS
RETURN
(
SELECT
OrderID,
OrderDate,
TotalAmount
FROM Sales.Orders
WHERE CustomerID = @CustomerID
);

Usage:

SELECT *
FROM dbo.fnOrdersByCustomer(100);

Characteristics of Inline TVFs

Inline TVFs:

  • Return a single SELECT statement
  • Do not declare table variables
  • Are generally optimized like parameterized views
  • Typically offer the best performance
  • Can participate fully in query optimization

For most scenarios, Microsoft recommends using inline TVFs whenever possible.


Multi-Statement Table-Valued Functions (MSTVFs)

A multi-statement TVF allows multiple T-SQL statements.

Unlike inline TVFs, it declares and populates a table variable.

Example:

CREATE FUNCTION dbo.fnLargeOrders
(
@MinimumAmount MONEY
)
RETURNS @Orders TABLE
(
OrderID INT,
CustomerID INT,
TotalAmount MONEY
)
AS
BEGIN
INSERT INTO @Orders
SELECT
OrderID,
CustomerID,
TotalAmount
FROM Sales.Orders
WHERE TotalAmount >= @MinimumAmount;
RETURN;
END;

Characteristics of Multi-Statement TVFs

MSTVFs:

  • Support multiple SQL statements
  • Allow procedural logic
  • Can declare variables
  • Can perform multiple INSERT operations into the return table
  • Are generally slower than inline TVFs because the optimizer has less information about the returned data

Comparing iTVFs and MSTVFs

FeatureInline TVFMulti-Statement TVF
Single SELECTYesNo
Multiple statementsNoYes
Table variableNoYes
Better optimizer supportYesLimited
Better performanceUsuallyUsually slower
Procedural logicLimitedYes

Using Parameters

TVFs commonly accept parameters.

Example:

SELECT *
FROM dbo.fnOrdersByCustomer(25);

Parameters make TVFs reusable across different queries.


Joining a TVF with Tables

Because TVFs return tables, they can participate in joins.

Example:

SELECT
c.CustomerName,
o.OrderID,
o.TotalAmount
FROM dbo.fnOrdersByCustomer(100) AS o
INNER JOIN Sales.Customers AS c
ON o.CustomerID = c.CustomerID;

Using CROSS APPLY

TVFs are frequently used with CROSS APPLY.

Example:

SELECT
c.CustomerID,
o.OrderID,
o.TotalAmount
FROM Sales.Customers AS c
CROSS APPLY dbo.fnOrdersByCustomer(c.CustomerID) AS o;

CROSS APPLY invokes the function once for each row returned by the outer query.

This is one of the most common uses of TVFs.


Using OUTER APPLY

OUTER APPLY behaves similarly to a left outer join.

Example:

SELECT
c.CustomerID,
o.OrderID
FROM Sales.Customers AS c
OUTER APPLY dbo.fnOrdersByCustomer(c.CustomerID) AS o;

Customers without matching orders still appear in the result set, with NULL values for the function’s columns.


Modifying a TVF

Use ALTER FUNCTION.

Example:

ALTER FUNCTION dbo.fnOrdersByCustomer
(
@CustomerID INT
)
RETURNS TABLE
AS
RETURN
(
SELECT
OrderID,
OrderDate,
TotalAmount,
Status
FROM Sales.Orders
WHERE CustomerID = @CustomerID
);

Dropping a TVF

Example:

DROP FUNCTION dbo.fnOrdersByCustomer;

Viewing a Function Definition

Developers can inspect the function definition using:

sp_helptext 'dbo.fnOrdersByCustomer';

Or:

SELECT OBJECT_DEFINITION(OBJECT_ID('dbo.fnOrdersByCustomer'));

Schema Binding

TVFs can be created using WITH SCHEMABINDING.

Benefits include:

  • Prevents incompatible schema changes
  • Improves object stability
  • Can be required for certain database features

Deterministic vs. Nondeterministic Functions

A TVF may be:

Deterministic

  • Same inputs produce the same outputs.

Nondeterministic

  • Results may change between executions.
  • Examples include functions using GETDATE() or NEWID().

Deterministic functions are generally preferred for predictable behavior and optimization.


TVFs vs. Views

FeatureTVFView
Accepts parametersYesNo
Returns a tableYesYes
ReusableYesYes
Can be parameterizedYesNo

One of the biggest advantages of a TVF over a view is its ability to accept parameters.


TVFs vs. Stored Procedures

FeatureTVFStored Procedure
Returns a tableYesCan return result sets but not as a table expression
Used in FROM clauseYesNo
Accepts parametersYesYes
Can participate in joinsYesNo

TVFs vs. Scalar Functions

FeatureTVFScalar Function
Returns a tableYesNo
Returns one valueNoYes
Used in FROM clauseYesNo
Used in expressionsNoYes

Performance Considerations

Performance is an important exam topic.

Inline TVFs

  • Usually have excellent performance.
  • The optimizer expands them into the calling query.
  • Can benefit from accurate cardinality estimation.
  • Often perform similarly to parameterized views.

Multi-Statement TVFs

  • Use a table variable internally.
  • Historically provided limited cardinality estimates, which could result in less efficient execution plans.
  • May perform more slowly on large result sets.

Whenever possible, use an inline TVF unless procedural logic requires a multi-statement implementation.


AI-Enabled Database Scenarios

TVFs are useful in AI-enabled database solutions because they provide reusable, parameterized datasets.

Examples include:

  • Returning embeddings associated with a specific document or tenant
  • Filtering vectors by category before similarity searches
  • Returning AI-ready feature sets for model inference
  • Preparing Retrieval-Augmented Generation (RAG) context based on user or document parameters
  • Returning standardized datasets for prompt construction
  • Producing reusable search result sets for intelligent search

Parameterized TVFs help AI applications retrieve only the data relevant to a specific request.


Best Practices

  • Prefer inline TVFs whenever possible.
  • Keep functions focused on a single responsibility.
  • Use meaningful names such as fnOrdersByCustomer.
  • Avoid unnecessary procedural logic.
  • Return only the columns required.
  • Keep functions deterministic whenever practical.
  • Test performance with realistic workloads.
  • Use CROSS APPLY or OUTER APPLY appropriately.
  • Document business logic within the function.
  • Review execution plans when TVFs are used in critical queries.

Common Exam Tips

For the DP-800 exam, remember these key points:

  • Table-valued functions return a table.
  • TVFs can accept parameters.
  • Inline TVFs contain a single SELECT statement.
  • Multi-statement TVFs populate a table variable using multiple statements.
  • Inline TVFs generally outperform multi-statement TVFs.
  • TVFs can be used in the FROM clause.
  • TVFs can participate in JOIN, CROSS APPLY, and OUTER APPLY operations.
  • Views cannot accept parameters, but TVFs can.
  • ALTER FUNCTION modifies an existing TVF.
  • DROP FUNCTION removes a TVF.

Practice Exam Questions

Question 1

A developer needs a reusable database object that accepts parameters and returns a result set that can be queried like a table. Which object should be used?

A. Stored procedure

B. Table-valued function

C. Scalar function

D. Trigger

Answer: B

Explanation: A table-valued function returns a table and can be referenced in the FROM clause while accepting input parameters.


Question 2

Which statement correctly describes an inline table-valued function?

A. It populates a table variable using multiple INSERT statements.

B. It returns exactly one scalar value.

C. It consists of a single SELECT statement that defines the returned table.

D. It cannot accept parameters.

Answer: C

Explanation: Inline TVFs are defined by a single SELECT statement and generally provide better performance because they integrate well with the query optimizer.


Question 3

What is one primary advantage of a table-valued function over a view?

A. It always performs faster.

B. It can automatically create indexes.

C. It can accept input parameters.

D. It can modify database schema.

Answer: C

Explanation: Unlike views, table-valued functions support input parameters, making them reusable for parameterized queries.


Question 4

A developer needs to use procedural logic and multiple INSERT statements to build a returned result set. Which type of function should be created?

A. Inline table-valued function

B. Scalar function

C. View

D. Multi-statement table-valued function

Answer: D

Explanation: Multi-statement TVFs allow multiple T-SQL statements and populate a table variable before returning it.


Question 5

Which operator is commonly used to invoke a table-valued function for each row returned by an outer query?

A. UNION

B. CROSS APPLY

C. EXISTS

D. PIVOT

Answer: B

Explanation: CROSS APPLY executes the TVF for each row in the outer query, making it ideal for parameterized row-by-row processing.


Question 6

Why do inline table-valued functions generally outperform multi-statement table-valued functions?

A. They automatically create clustered indexes.

B. They execute in parallel regardless of the query.

C. They are optimized similarly to parameterized views, allowing better query optimization.

D. They always return fewer rows.

Answer: C

Explanation: The SQL Server optimizer can expand inline TVFs into the calling query, producing more efficient execution plans than are typically possible with multi-statement TVFs.


Question 7

Which statement about table-valued functions is correct?

A. They can only return one column.

B. They cannot participate in JOIN operations.

C. They cannot accept parameters.

D. They can be queried in the FROM clause just like a table.

Answer: D

Explanation: TVFs return a table and can be used in the FROM clause, joined with other tables, and filtered like regular tables.


Question 8

Which statement should be used to modify an existing table-valued function?

A. UPDATE FUNCTION

B. MODIFY FUNCTION

C. CREATE FUNCTION

D. ALTER FUNCTION

Answer: D

Explanation: ALTER FUNCTION changes the definition of an existing table-valued function while preserving the object.


Question 9

A developer wants all customers returned, even if a table-valued function produces no matching rows for some customers. Which operator should be used?

A. INNER JOIN

B. CROSS APPLY

C. OUTER APPLY

D. INTERSECT

Answer: C

Explanation: OUTER APPLY behaves similarly to a left outer join, returning all rows from the outer query and NULL values when the TVF produces no matching rows.


Question 10

How can table-valued functions support AI-enabled database solutions?

A. They automatically train machine learning models.

B. They replace vector indexes.

C. They provide reusable, parameterized datasets that simplify intelligent search, feature retrieval, and Retrieval-Augmented Generation (RAG) workflows.

D. They eliminate the need for indexes.

Answer: C

Explanation: TVFs encapsulate reusable, parameterized query logic, making them well suited for AI scenarios such as feature retrieval, intelligent search, and RAG, where filtered and consistent datasets are required.


Go to the DP-800 Exam Prep Hub main page