flawopen.com/SQL Injection/Numeric IDs
The risk was never about the value's real-world meaning — it's about the fact that the query is built by gluing text together at all. "This is always a number" is an assumption about the data, not a guarantee enforced by the code.
A URL query parameter or form field is text on the wire, regardless of what the database column behind it expects. Nothing stops an attacker from sending id=1 OR 1=1 instead of a number — the web framework doesn't reject it before your code sees it unless you explicitly validate the type.
Code that's safe today because the ID genuinely always comes from a trusted internal source can become unsafe the moment a new caller passes a user-supplied value into the same function — the vulnerability was latent the whole time, waiting for that change.
In dynamically typed languages especially, a value that looks numeric when logged or debugged can still be a string containing extra characters — the type you expect and the type you actually have aren't guaranteed to match without explicit validation.
Parameterized queries don't require knowing or trusting the value's type in advance — the database driver handles a numeric-looking string exactly as safely as a genuinely malicious one, because the value never becomes part of the query text either way. There's no performance or ergonomic reason to skip parameterization "because this one's just a number."