Stored functions
CREATE FUNCTION, DETERMINISTIC, using your own functions in queries and when to prefer procedures.
A stored function is a user-defined function written in SQL. Unlike a procedure, it returns a single value and can be used anywhere an expression is allowed: in SELECT lists, WHERE clauses, ORDER BY and UPDATE ... SET. Functions are great for packaging a calculation or business rule that many queries share.
Creating a function#
The parts:
RETURNS type: the type of the single value returned.- Function parameters are always
IN, so you don't writeIN/OUT. RETURN exprends the function and gives back the value.- Characteristics describe the function to MySQL:
DETERMINISTIC: the same inputs always give the same result (NOT DETERMINISTICis the default).NO SQL: doesn't touch tables.READS SQL DATA: reads but doesn't modify.MODIFIES SQL DATA: writes.
For a one-line function you can skip BEGIN ... END (and the DELIMITER change):
Why the characteristics matter#
When binary logging is enabled (the default in MySQL 8, and required for replication and point-in-time recovery), MySQL refuses to create a function unless you declare it DETERMINISTIC, NO SQL or READS SQL DATA:
This protects replicas: a non-deterministic function that modifies data could produce different results when the binary log is replayed. Declare characteristics honestly. Lying (marking a RAND()-based function as DETERMINISTIC) can make replicas drift or give wrong results. An administrator can relax the rule with SET GLOBAL log_bin_trust_function_creators = 1;, but honest declarations are better:
Functions that read tables#
Neat, but be aware of the cost. This function runs a query for every row it's called on, and twice per row here (once in SELECT, once in ORDER BY). On a table of a million customers, that's millions of small queries, and the optimiser can't see inside the function to combine them. A join with GROUP BY does the same work in a single pass:
Rule of thumb: functions that only compute from their arguments (NO SQL) are cheap and great. Functions that query tables are convenient for single-row lookups but risky in queries over many rows.
Using functions in WHERE and indexes#
As with built-in functions, wrapping a column in a function in WHERE prevents a normal index from being used. MySQL 8's functional indexes only accept built-in deterministic functions, not stored functions. For a computed value you filter on often, store it in a generated column instead:
Restrictions#
Inside a stored function you can't:
- start, commit or roll back transactions,
- return a result set (a bare
SELECTwithoutINTO), - use dynamic SQL (
PREPARE/EXECUTE), - modify the table the calling statement is reading from.
If you need any of these, write a procedure.
Managing functions#
Callers need the EXECUTE privilege, and creators need CREATE ROUTINE. Like procedures, functions run with SQL SECURITY DEFINER by default.
Function or procedure?#
What's next#
Functions and procedures run when you call them. Triggers run automatically when rows change, and events run on a schedule. That's next.
Check your understanding
Quick quiz
1.What is the key practical difference between a stored function and a stored procedure?
2.With binary logging on, creating a function without DETERMINISTIC, NO SQL or READS SQL DATA fails with error 1418. Why?
3.Which statement is NOT allowed inside a stored function?
Finished reading?
Mark this lesson complete to track your progress.