我正在尝试编写一个存储过程,该过程返回一个对象列表,其中包含用户选择的排序顺序和排序方向,并作为sql参数传入 .
假设我有一个包含以下列的产品表:product_id(int),name(varchar),value(int),created_date(datetime)和参数@sortDir和@sortOrder
我想做点什么
select *
from Product
if (@sortOrder = 'name' and @sortDir = 'asc')
then order by name asc
if (@sortOrder = 'created_date' and @sortDir = 'asc')
then order by created_date asc
if (@sortOrder = 'name' and @sortDir = 'desc')
then order by name desc
if (@sortOrder = 'created_date' and @sortDir = 'desc')
then order by created_date desc
我尝试用case语句做,但由于数据类型不同而遇到了问题 . 有人有什么建议吗?
4 回答
你需要一个case语句,尽管我会使用多个case语句:
有四个不同的子句消除了类型之间转换的问题 .
CASE
是一个返回值的表达式 . 它不适用于流量控制,如IF
. 并且您不能在查询中使用IF
.不幸的是,
CASE
表达式存在一些限制,这使得执行您想要的操作变得很麻烦 . 例如,CASE
表达式中的所有分支必须返回相同的类型,或者可以隐式转换为相同的类型 . 我不会't try that with strings and dates. You also can'使用CASE
来指定排序方向 .一个可以说更简单的解决方案(特别是如果这变得更复杂)是使用动态SQL . 要阻止SQL注入,您可以测试值:
动态SQL的另一个好处,尽管所有恐慌都在其中传播:您可以为每种排序变化获得最佳计划,而不是一个单独的计划,它将优化您最初使用的任何类型变化 . 在我最近的一次性能比较中,它也表现得最好:
http://sqlperformance.com/conditional-order-by
有多种方法可以做到这一点 . 一种方法是:
您也可以使用动态sql来完成它 .