【发布时间】:2009-07-31 21:09:42
【问题描述】:
在 ADO.NET 中参数化 order by 子句的正确方法是什么?
有时需要按 2 列排序,而默认情况下仅按 1 列排序,有时您只想将 ASC 更改为 DEC。 在这种情况下是否可以只使用字符串连接(假设输入不是直接来自用户,而只是在代码中查找或多或少的硬编码值)
【问题讨论】:
在 ADO.NET 中参数化 order by 子句的正确方法是什么?
有时需要按 2 列排序,而默认情况下仅按 1 列排序,有时您只想将 ASC 更改为 DEC。 在这种情况下是否可以只使用字符串连接(假设输入不是直接来自用户,而只是在代码中查找或多或少的硬编码值)
【问题讨论】:
试试这样:
SELECT ...
ORDER BY
CASE WHEN @OrderBy = 'Option1' THEN SomeField END,
CASE WHEN @OrderBy = 'Option1' THEN SomeOtherField END DESC,
CASE WHEN @OrderBy = 'Option2' THEN Field75 END,
...
这个想法是,如果 WHEN 不匹配,每个 CASE 语句都将评估为 NULL。因此,如果您输入 Option2,那么您将获得前两个选项的常量值。
因此,使用它,您可以轻松获得一些选项,让您按多个字段或降序或任何您想要的方式排序。
罗伯
【讨论】:
SQL 注入纯粹主义者会告诉你,字符串连接是绝对不允许的,因为总是存在其他程序员可能扩展程序并将 SQL 语句暴露给外界的可能性。
但是,如果这些值是硬编码的(即作为常量),并且永远不会看到外部世界,那么是的,连接它是完全可以的。
【讨论】:
只要不允许用户通过文本输入或可能通过 url 访问变量,我看不出使用字符串连接有任何负面原因。除非像下面的人说的那样,该程序可能会由不那么“有注入意识”的其他用户扩展。
【讨论】:
有不使用动态 SQL 的纯 T-SQL 解决方案。
这里有一些答案:Dynamic order direction。接受的答案和我的答案展示了这两种方法。不过也许是特定于 SQL Server 的。
【讨论】:
如果没有那么多数据,我会:
DataTable dt = ....
DataView dv = new DataView(dt);
dv.Sort = "LastName DESC, FistName";
然后根据任何内容改变最后一行。
【讨论】:
示例:
SELECT 1 AS Num, '2015-06-22' AS Datex INTO Arya
INSERT INTO Arya
SELECT 2, '2015-08-17' UNION SELECT 3, '2015-07-14'
艾莉亚表:
Num Datex
-----------------
1, 2015-06-22
2, 2015-08-17
3, 2015-07-14
现在,在 SELECTION 中参数化排序(基于 Datex 字段)......
SELECT Num, Date1 FROM ARYA, (SELECT -1 as e union Select 1 as e) a
WHERE a.e=1 --(1) For ASC sort --(OR a.e=-1) For Desc Sort
ORDER BY DATEDIFF(DAY, '2000-01-01', Arya.Datex)*a.e
Result: ASC Sort IF 1
1, 2015-06-22
3, 2015-07-14
2, 2015-08-17
Result: ASC Sort IF -1
2, 2015-08-17
3, 2015-07-14
1, 2015-06-22
【讨论】: