2010-02-17 78 views
1

我有一个存储过程,它接收一个字符串参数“OrderByColumn”并相应地构建动态查询。
这是我的存储过程的代码部分:动态查询和sql注入

ROW_NUMBER() OVER (ORDER BY 
    CASE WHEN @OrderByColumn='Date' AND @OrderDirection=0 THEN tbl_Docs.Date END ASC, 
    CASE WHEN @OrderByColumn='Count' AND @OrderDirection=0 THEN tbl_Docs.Count END ASC, 

而且在后面的功能我的代码调用存储过程,我有:

cmd.Parameters.Add("@OrderByColumn", SqlDbType.NVarChar).Value = orderByColumn; 
cmd.Parameters.Add("@OrderDirection", SqlDbType.Int).Value = orderDirection; 

用户通过点击设置OrderByColumn参数gridviews列标题,所以没有直接的用户输入,所以我看到没有选择注入任何东西...

在书中,他们还验证orderByColumn字符串,我不明白为什么它需要,因为正如我注意到的,用户不能输入直接表达式。

我的问题是:

是否安全?

我也读过一些书,ORDER BY子句不支持使用参数。
这是什么意思?

+0

你为什么不使用orm? – Paco 2010-02-17 11:19:15

+0

围绕ORDER BY的问题的最后一部分是您必须明确定义列名称。 – 2010-02-17 11:20:13

回答

1

这看起来足够安全,可以使用。

我不是完全跟随这部分

我也看过一些书的顺序 BY子句不支持使用 参数。

您的意思是ORDER(ASC/DESC)或列吗?

如果您正在引用该列,则可以实现此目的。喜欢的东西

DECLARE @Table TABLE(
     ID INT, 
     Val INT 
) 

INSERT INTO @Table SELECT 1, 3 
INSERT INTO @Table SELECT 2, 2 
INSERT INTO @Table SELECT 3, 1 

DECLARE @FieldNumber INT 

SELECT @FieldNumber = 1 

SELECT * 
FROM @Table 
ORdER BY 
      CASE @FieldNumber 
       WHEN 1 THEN ID 
       WHEN 2 THEN Val 
      END 

SELECT @FieldNumber = 2 

SELECT * 
FROM @Table 
ORdER BY 
      CASE @FieldNumber 
       WHEN 1 THEN ID 
       WHEN 2 THEN Val 
      END 
+0

如果我这样做了“case”,那么我将无法在其末尾添加:ASC/DESC。 – mariki 2010-02-17 17:05:04

0

验证不仅局限于SqlInjection攻击,还有许多其他原因可以验证输入。

Parameters的处理方式与OVER子句中的处理方式相同,因为constant被忽略。所以它基本上不是支持参数的问题,而是你得到的结果,它不受使用的影响

0

我认为它是安全的,以及...参数的内容不被直接计入存储过程所发出的查询 - 你只是测试参数去决定要放什么查询自己。

我认为你可以问心无愧......

1

是它的安全?
是的,这似乎很好。该值不会被连接成一个SQL字符串然后被执行,而且您实际上正在验证显式检查某些有效值。

我也读过一些书,ORDER BY子句不支持使用参数。 这是什么意思?
这意味着你不能做(例如,)“ORDER BY @SomeVariable”其中@SomeVariable是要排序的列。因此,您需要像使用CASE一样使用CASE方法。