Keep SQL values out of SQL syntax
Interpolating a user value into SQL lets quotes change the meaning of the query. Parameters transmit values separately from the statement. They also handle empty strings and embedded quotes without manual escaping. An in-memory SQLite database is enough to practise this boundary, and results should have an explicit order so callers receive predictable output.
import sqlite3
con = sqlite3.connect(":memory:")
row = con.execute("SELECT ?", ("O'Neil",))
print(row.fetchone())Think before coding
The SQL statement never changes when the input changes. Using substr gives literal prefix semantics without LIKE escaping, and ORDER BY makes the output deterministic. Work through the example by hand before changing the starter. Decide what should happen for an empty input, a single value and a repeated value where those cases apply. The checks use several inputs so a hard-coded answer cannot stand in for the rule.
Your task
Write lookup_names(connection, prefix). The connection has people(name TEXT). Return names beginning with the literal prefix, sorted by name. Use a bound parameter. Percent and underscore in the prefix are literal characters, not LIKE wildcards.
The explanation opens here once every check passes.