Consider this table:

Now say we want to create a stored procedure to read from it - and we want to be able to specify which column to sort on.
A solution like this:
create proc temp_GetPlayers(@sOrderBy varchar(20))
as
exec('select * from player order by ' + @sOrderBy )
would let us run things like:
temp_GetPlayers 'pos'
temp_GetPlayers 'height'
and even
temp_GetPlayers 'pos desc'
However dynamically constructing sql and EXECuting them are not recommended, there are performance considerations (no precompilation) and also it opens up for sql injection. What if the @sOrderBy was taken from ASP.NET Request[] collection - it would then be possible to send in "pos; delete from immortantable" in the querystring and that's a classic sql injection...
Lets try to use integers instead:
alter proc temp_GetPlayers(@nOrderBy int)
as
select * from player
order by
case when @nOrderBy = 1 then pos
when @nOrderBy = 2 then shoots
else namn
end
Using integers is injection safe. We call it like temp_GetPlayers 1, temp_GetPlayers 2 etc.
However - we do have a problem with this approach...The case statement can only work with one sinle datatype - meaning we cant do this:
alter proc temp_GetPlayers(@nOrderBy int)
as
select * from player
order by
case when @nOrderBy = 1 then pos
when @nOrderBy = 2 then shoots
when @nOrderBy = 3 then height
else namn
end
you will now get an error like
Syntax error converting the varchar value 'L' to a column of data type int.
So, the solution is to cast:
alter proc temp_GetPlayers(@nOrderBy int)
as
select * from player
order by
case when @nOrderBy = 1 then pos
when @nOrderBy = 2 then shoots
when @nOrderBy = 3 then CAST(height AS VARCHAR(50))
else namn
end
Still, this technique is still not optimal - we can't dynamically specify asc/desc ordering. However, as always, the solution is not optimal - but - it might be good enough.