How to select from MySQL where Table name is Variable
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In MySQL, you cannot parameterize a table name in a normal prepared statement placeholder the way you parameterize a value. If the table name must vary, the usual solution is dynamic SQL: build the statement as a string, validate the table name carefully, then prepare and execute it.
Core Sections
Why placeholders do not work for table names
This does not work:
The reason is that ? placeholders are for values, not SQL identifiers such as table names, column names, or database names. MySQL parses the structure of the SQL statement before binding values, so the table must already be part of the statement text.
Build the SQL dynamically
The standard MySQL pattern is:
- put the table name into a string
- concatenate the SQL text
PREPAREthe statementEXECUTEit
The table name is injected into the SQL text itself, while the id value remains a normal bound parameter.
Validate the table name before executing
This is the critical safety rule. If the table name comes from user input, do not concatenate it blindly. Since identifiers cannot use placeholders, you must whitelist acceptable names yourself.
For example, in application code:
Then build the SQL only after the identifier has passed validation. Dynamic SQL with unvalidated identifiers is an SQL injection risk.
Stored procedure example
If the logic lives inside MySQL, a stored procedure can wrap the dynamic query:
Even here, the procedure should still enforce a whitelist if p_table can vary freely.
Often the design should be reconsidered
A variable table name is sometimes a sign that the schema design is fighting the query. If several tables have the same structure and differ only by a category, a single table with a type column is often easier to query, index, and maintain.
Dynamic table selection is still valid in some cases, such as partitioned historical tables or admin tooling, but it should be a deliberate design choice rather than the default answer.
Common Pitfalls
- Trying to use
?placeholders for table names even though placeholders only work for values. - Concatenating untrusted user input directly into SQL identifiers.
- Forgetting to
DEALLOCATE PREPAREafter executing dynamic SQL repeatedly. - Using dynamic table names where a cleaner schema could avoid the problem entirely.
- Treating identifier validation as optional just because the query is built on the server side.
Summary
- MySQL does not let you bind a table name through a normal placeholder.
- Use dynamic SQL with
CONCAT,PREPARE, andEXECUTEwhen the table name must vary. - Keep values parameterized even when the identifier itself is dynamic.
- Always validate dynamic table names against a trusted whitelist.
- If variable table names appear everywhere, revisit the schema before doubling down on dynamic SQL.

