Scalar vs Inline TVF vs Multi-Statement TVF: Choosing the Right SQL Server Function Type
Three function types, three very different performance profiles โ now that you’ve built one of each, here’s the decision made simple, plus the stored-procedure exit ramp that applies whenever none of the three actually fit.
Side by Side
| Scalar | Inline TVF | Multi-statement TVF | |
|---|---|---|---|
| Returns | One value | A table | A table |
| Optimizer visibility | Limited (improved 2019+) | Full โ inlines like a view | None โ black box, fixed row estimate |
| Procedural logic | Yes | No, single SELECT only | Yes |
| Usable inside a JOIN | N/A (scalar value) | Yes, joins like a table | Yes, joins like a table |
| Default preference | 3rd choice | 1st choice | Last resort โ consider a procedure first |
The Decision Flow
The Real Decision Isn’t Always Among These Three
The most important line in the flowchart is the last branch: “mTVF or Procedure.” If you need to modify data (INSERT/UPDATE/DELETE), manage a transaction, or use TRY/CATCH error handling โ none of which any function type can do โ that’s your unambiguous signal to write a stored procedure instead, which is exactly where the next chapter picks up. Functions are for computing and returning values; procedures are for doing things, including things that change data.
-- FAILS: functions cannot modify data outside a local table variable
CREATE FUNCTION dbo.BadIdea (@id INT) RETURNS INT AS
BEGIN
UPDATE dbo.Employee SET last_login = GETDATE() WHERE employee_id = @id; -- not allowed
RETURN 1;
END;
-- Msg 443: Invalid use of a side-effecting operator 'UPDATE' within a function.
This restriction isn’t arbitrary โ it’s what allows functions to be safely called from inside a SELECT list or WHERE clause at all. If functions could silently modify data, using one inside a SELECT would make the query’s meaning depend on evaluation order, which SQL’s set-based model deliberately doesn’t guarantee.
Key Takeaways
- Default to iTVF whenever a single SELECT expresses the logic โ it’s the best-performing option, with zero downside versus writing the JOIN by hand
- Scalar functions are fine for reusable expressions on modest data volumes, called outside a large table’s WHERE clause
- mTVFs and stored procedures both handle procedural logic โ if you need to modify data or manage transactions, that’s your firm signal to reach for a procedure instead, since no function type permits it
Enjoyed this?
Subscribe to get every new SQL Server lesson as soon as it’s published, and share it with a developer who’d find it useful.
๐ก Subscribe via RSS |
Share on X |
Share on LinkedIn |
Share on Facebook
Want the full structured course with quizzes, projects, and 10+ exercises per chapter? Check out SQL Server for Developers & DBAs, coming soon on this site.