Dynamic SQL lets you build and run SQL commands on the fly. This helps when you don't know the exact query until your program runs.
Dynamic SQL with EXECUTE in PostgreSQL
Start learning this pattern below
Jump into concepts and practice - no test required
or
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Syntax
PostgreSQL
EXECUTE 'sql_command_string';The SQL command must be a string inside single quotes.
Use EXECUTE inside PL/pgSQL functions or DO blocks to run dynamic SQL.
Examples
PostgreSQL
EXECUTE 'SELECT * FROM users WHERE id = 1';PostgreSQL
EXECUTE format('SELECT * FROM %I WHERE %I = %L', table_name, column_name, value);PostgreSQL
EXECUTE 'UPDATE ' || table_name || ' SET name = ''John'' WHERE id = 5';
Sample Program
This block runs a dynamic SELECT query on the 'employees' table to find someone in the 'Sales' department. It uses EXECUTE with format() for safety. It then prints a message depending on the result.
PostgreSQL
DO $$ DECLARE table_name text := 'employees'; column_name text := 'department'; value text := 'Sales'; result record; BEGIN EXECUTE format('SELECT * FROM %I WHERE %I = %L', table_name, column_name, value) INTO result; IF result IS NOT NULL THEN RAISE NOTICE 'Found employee in %', result.department; ELSE RAISE NOTICE 'No employee found in %', value; END IF; END $$;
Important Notes
Always use format() with %I and %L to safely insert identifiers and literals to avoid SQL injection.
EXECUTE runs inside PL/pgSQL blocks, not in plain SQL queries.
Dynamic SQL is powerful but can be harder to debug, so test carefully.
Summary
Dynamic SQL with EXECUTE lets you run SQL commands built during program execution.
Use it when queries need to change based on input or conditions.
Always build dynamic queries safely to avoid errors and security risks.
Practice
1. What is the main purpose of using
EXECUTE in PostgreSQL dynamic SQL?easy
Solution
Step 1: Understand dynamic SQL concept
Dynamic SQL means building SQL commands as text during program run time, not fixed in advance.Step 2: Role of EXECUTE
EXECUTE runs these dynamically created SQL commands inside PostgreSQL.Final Answer:
To run SQL commands that are created during the execution of a program -> Option AQuick Check:
Dynamic SQL = EXECUTE runs built queries [OK]
Hint: EXECUTE runs SQL built as text during program run [OK]
Common Mistakes:
- Thinking EXECUTE stores queries permanently
- Confusing EXECUTE with static SQL execution
- Assuming EXECUTE creates tables automatically
2. Which of the following is the correct syntax to execute a dynamic SQL query stored in a variable
sql_query inside a PL/pgSQL function?easy
Solution
Step 1: Recall EXECUTE syntax in PL/pgSQL
In PL/pgSQL, the correct command to run a dynamic SQL string is EXECUTE followed by the variable.Step 2: Check other options
RUN and EXEC are not valid PostgreSQL commands; PERFORM runs a static query, not dynamic SQL string.Final Answer:
EXECUTE sql_query; -> Option AQuick Check:
EXECUTE runs dynamic SQL string [OK]
Hint: Use EXECUTE to run dynamic SQL strings in PL/pgSQL [OK]
Common Mistakes:
- Using RUN or EXEC which are invalid in PostgreSQL
- Confusing PERFORM with EXECUTE for dynamic SQL
- Missing semicolon after EXECUTE statement
3. Consider this PL/pgSQL snippet:
What will this function return when called if the
DECLARE table_name text := 'users'; rec_count int; BEGIN EXECUTE 'SELECT count(*) FROM ' || table_name INTO rec_count; RETURN rec_count; END;
What will this function return when called if the
users table has 10 rows?medium
Solution
Step 1: Understand dynamic SQL concatenation
The query string becomes 'SELECT count(*) FROM users', which is valid SQL.Step 2: EXECUTE runs the query and stores result
EXECUTE runs the query and puts the count into rec_count variable.Final Answer:
10 -> Option DQuick Check:
Count rows in users = 10 [OK]
Hint: Concatenate table name safely, EXECUTE runs query, INTO stores result [OK]
Common Mistakes:
- Expecting error due to missing quotes around table name
- Assuming rec_count stays NULL without assignment
- Confusing dynamic SQL with static SQL syntax
4. What is the error in this PL/pgSQL code snippet?
DECLARE col_name text := 'age'; val int := 30; BEGIN EXECUTE 'SELECT * FROM people WHERE ' || col_name || ' = val'; END;
medium
Solution
Step 1: Analyze dynamic SQL string construction
The string becomes 'SELECT * FROM people WHERE age = val', where val is literal text, not variable value.Step 2: Understand variable substitution in EXECUTE
Variables must be concatenated or passed using USING clause to substitute values properly.Final Answer:
The variable val is not substituted inside the dynamic SQL string -> Option CQuick Check:
Variables need USING or concatenation in EXECUTE [OK]
Hint: Use USING or concatenate variables in EXECUTE strings [OK]
Common Mistakes:
- Assuming variables auto-substitute inside strings
- Forgetting to use USING clause with EXECUTE
- Thinking EXECUTE can't be inside BEGIN...END
5. You want to write a PL/pgSQL function that takes a table name and a column name as inputs and returns the maximum value in that column. Which approach correctly uses dynamic SQL with EXECUTE to achieve this safely?
hard
Solution
Step 1: Understand safe dynamic SQL construction
Using format() with %I safely quotes identifiers like column and table names to avoid SQL injection.Step 2: Check other options for safety and correctness
EXECUTE 'SELECT max(' || col_name || ') FROM ' || table_name INTO result; concatenates strings directly (unsafe). EXECUTE 'SELECT max($1) FROM $2' USING col_name, table_name INTO result; uses placeholders incorrectly for identifiers. EXECUTE 'SELECT max(:col_name) FROM :table_name' INTO result; uses invalid syntax.Final Answer:
EXECUTE format('SELECT max(%I) FROM %I', col_name, table_name) INTO result; -> Option BQuick Check:
Use format() with %I for identifiers in EXECUTE [OK]
Hint: Use format() with %I to safely insert identifiers in EXECUTE [OK]
Common Mistakes:
- Concatenating identifiers without quoting
- Using placeholders for table/column names
- Incorrect EXECUTE syntax with named parameters
