Constructing and executing a SQL statement as a string at runtime, allowing the query structure to vary based on input.
Pre-compiled SQL templates that can be executed with different parameter values, improving performance for repeated queries and preventing SQL injection. Parameters are bound rather than concatenated, separating code from data.
| Database System | Support Status | Since Version | Notes |
|---|---|---|---|
| MySQL | ✓ Supported | 5.0 | PREPARE/EXECUTE/DEALLOCATE PREPARE syntax works inside stored routines and at the session level. Parameterized via USING. |
| PostgreSQL | ✓ Supported | 7.4 | EXECUTE inside PL/pgSQL runs dynamic SQL. USING clause passes parameters safely. format() with %I/%L helps prevent injection. |
| SQL Server | ✓ Supported | 2005 | sp_executesql is preferred over EXEC(@sql) because it supports parameterization and plan reuse. Always use sp_executesql for user-supplied values. |
| Oracle | ✓ Supported | 8i | EXECUTE IMMEDIATE is the standard PL/SQL mechanism. DBMS_SQL package provides a lower-level cursor API for cases where column count is unknown at compile time. |
| SQLite | ✗ Not Supported | — | No server-side dynamic SQL. The application layer must construct and submit statements via the sqlite3 C API or a driver. |
Dynamic SQL is a necessary evil for cases like pivot columns, table-name parameters, or optional filter clauses. The biggest portability concern is SQL injection: always use parameterized queries (USING / sp_executesql parameters / EXECUTE IMMEDIATE USING) rather than string concatenation with user input. PostgreSQL's format() function with %I (identifier quoting) and %L (literal quoting) is particularly ergonomic. SQL Server's sp_executesql additionally enables plan caching since the parameterized template is stable across calls. Oracle's DBMS_SQL package is needed when the number or types of output columns are unknown at compile time — otherwise EXECUTE IMMEDIATE is simpler. MySQL's PREPARE/EXECUTE works at the session level without a stored procedure, which is unique among these engines.
PREPARE/EXECUTE/DEALLOCATE PREPARE syntax works inside stored routines and at the session level. Parameterized via USING.
EXECUTE inside PL/pgSQL runs dynamic SQL. USING clause passes parameters safely. format() with %I/%L helps prevent injection.
sp_executesql is preferred over EXEC(@sql) because it supports parameterization and plan reuse. Always use sp_executesql for user-supplied values.
EXECUTE IMMEDIATE is the standard PL/SQL mechanism. DBMS_SQL package provides a lower-level cursor API for cases where column count is unknown at compile time.