Named, reusable routines that accept parameters, compute a value, and return a scalar or table result.
Database-specific procedural extensions: PL/pgSQL in PostgreSQL, T-SQL in SQL Server, PL/SQL in Oracle. Allow complex logic, loops, and conditionals in the database. Powerful but can become a maintenance burden and are hard to test.
| Database System | Support Status | Since Version | Notes |
|---|---|---|---|
| MySQL | ✓ Supported | 5.0 | Scalar functions only (no table-valued UDFs in native SQL). DETERMINISTIC / NO SQL / READS SQL DATA characteristics affect optimizer behavior. |
| PostgreSQL | ✓ Supported | 6.5 | Supports scalar and set-returning (RETURNS TABLE / RETURNS SETOF) functions. LANGUAGE can be sql, plpgsql, python, c, and more. |
| SQL Server | ✓ Supported | 2000 | Three types: scalar, inline table-valued (ITVF), and multi-statement table-valued (MSTVF). ITVFs are strongly preferred over MSTVFs for performance. |
| Oracle | ✓ Supported | 7 | Functions can use PIPELINED RETURN to stream table results row by row. DETERMINISTIC hint improves optimizer reuse. |
| SQLite | ✓ Supported | 3.0.0 | UDFs must be registered at the connection level via the application API (e.g., sqlite3_create_function in C, or conn.create_function() in Python). No CREATE FUNCTION DDL. |
UDFs are supported everywhere but vary widely in capability and performance characteristics. SQL Server scalar UDFs are infamous for row-by-row execution that defeats parallelism — inline table-valued functions (single SELECT, no BEGIN/END) are the idiomatic replacement for scalar logic that operates on sets. PostgreSQL's function overloading (same name, different argument types) is unique among the five engines. Oracle PIPELINED functions allow lazy evaluation of large result sets. MySQL's lack of table-valued UDFs means pivoting or multi-row generation requires stored procedures or workarounds. SQLite's approach — registering functions in the host language rather than via DDL — is architecturally different and means UDFs don't persist across connections unless re-registered.
Scalar functions only (no table-valued UDFs in native SQL). DETERMINISTIC / NO SQL / READS SQL DATA characteristics affect optimizer behavior.
Supports scalar and set-returning (RETURNS TABLE / RETURNS SETOF) functions. LANGUAGE can be sql, plpgsql, python, c, and more.
Three types: scalar, inline table-valued (ITVF), and multi-statement table-valued (MSTVF). ITVFs are strongly preferred over MSTVFs for performance.
Functions can use PIPELINED RETURN to stream table results row by row. DETERMINISTIC hint improves optimizer reuse.
UDFs must be registered at the connection level via the application API (e.g., sqlite3_create_function in C, or conn.create_function() in Python). No CREATE FUNCTION DDL.