you bind the string value 'name'
to the parameter in the sql. That means that for each row processed, the SQL will see the same string, namely 'name'
.
The point is that 'name' is not interpreted as the Literal name
which matches the column name, but a VARCHAR value 'name'
which has been set or bound to a replacement variable ?
.
In this case, if you have a variable ORDER BY
clause, you would have two (or more) versions of your SQL, which you can select with a regular if
/ then
/ else
.
Another way is to concatenate the sorting column in your string directly rather than using bind variables. I would STRONGLY suggest against as this lays the foundation work for future SQL Injection. Either way, if you concatenate a variable input string to your SQL, then make sure it is sufficiently sanitized and checked to avoid issues.
Concatenation in PHP would be something simple like this:
$orderby = "name";
$stmt = $conn->prepare("SELECT id, name FROM user order by ".$orderby." desc");
$stmt->execute();
See also PHP - concatenate or directly insert variables in string (had to correct, used initially a syntax that only worked for the PHP echo
command).
All the other Implementing Languages (C#, Java, etc) combined with any database (oracle, MySQL, TSQL, etc) would face same issues and solutions: You will have to make the distinction between bind variables and literals in your SQL.
If you still want to use a bind variable - there is a way, but you would have to modify your sql as follows:
SELECT id, name FROM user
ORDER BY CASE ? WHEN 'name' THEN name WHEN 'id' THEN id ELSE NULL END
Actually good thinking by you (in your comment) to still use bind variables somehow. Now I do not have the issue with SQL Injection anymore either. However, now you need to account for every possible sorting that can happen, and have that coded in your SQL instead.