使用SqlParameter创建Order By子句

Ste*_*aly 14 c# sql-server asp.net

我试图将我对SQL语句中的变量的所有引用移动到SqlParameter类,但由于某种原因,此查询失败.

string orderBy = Request.QueryString["OrderBy"];
//Fix up the get vars
if (orderBy == null)
    orderBy = "name ASC";

string selectCommand = "SELECT cat_id AS id, cat_name AS name FROM table_name ORDER BY @OrderBy";
SqlCommand cmd = new SqlCommand(selectCommand, dataConnection);
cmd.Parameters.Add(new SqlParameter("@OrderBy", orderBy));

//Create the SQLDataAdapter instance
SqlDataAdapter dataCommand = new SqlDataAdapter(cmd);

//Create the DataSet instance
DataSet ds = new DataSet();
//Get data from a server and fill the DataSet  
dataCommand.Fill(ds);
Run Code Online (Sandbox Code Playgroud)

这是错误

System.Data.SqlClient.SqlException:由ORDER BY编号1标识的SELECT项包含一个变量,作为标识列位置的表达式的一部分.只有在引用列名的表达式进行排序时,才允许使用变量.

它失败了.

dataCommand.Fill(ds);
Run Code Online (Sandbox Code Playgroud)

Con*_*rix 13

你真的有三个选择.

1)使用数据视图来排序结果集

2)如果你知道可以订购的列,你可以测试字符串,然后使用然后选择订单.例如

例如,这将有效

DECLARE @orderby varchar(255)
SET @orderby = 'Name ASC'

SELECT [Your Column here ]FROM sys.tables 
ORDER BY    
   case WHEN @orderby = 'Name ASC' Then name ELSE null END ASC,
   case WHEN @orderby = 'Name DESC' Then name ELSE null END DESC,
   CASE WHEN @orderby = 'Object_id ASC' then object_id ELSE null END ASC,
   CASE WHEN @orderby = 'Object_id DESC' then object_id ELSE null END DESC
Run Code Online (Sandbox Code Playgroud)

3)最后的选择是和#2一样,但是在你的C#代码中.请确保您不仅仅是从用户输入中添加ORDER BY子句,因为这对于SQL注入是有效的.

这是安全的,因为OrderBy Url参数"Name Desc; DROP table Users"将被忽略

string SafeOrderBy = "";
string orderBy = Request.QueryString["OrderBy"];
//Fix up the get vars
if (orderBy == null)
    orderBy = "name ASC";

if (orderby == "name Desc")
{
     SafeOrderBy == "name Desc"
}


string selectCommand = "SELECT cat_id AS id, cat_name AS name FROM table_name ORDER BY "
selectCommand  += SafeOrderBy ;
Run Code Online (Sandbox Code Playgroud)