我有以下MS SQL存储过程。我需要在不使用动态SQL和sp_executesql
方法
@Order by可以包含可能的值ProductName ASC
,ProductName DESC
,ProductCode ASC
,VendorName DESC
,VendorCode
或ClientName
我试图使用ORDER BY CASE
,如果ProductName
,ProductCode
属于不同类型,是否有任何问题?
ALTER PROCEDURE [dbo].[SortedReport]
(
@ClientID INT,
@RecordLimit,
@FromDate DATETIME,
@ToDate DATETIME,
@OrderBy NVARCHAR(MAX)
)
AS
BEGIN
IF (@OrderBy IS NULL) BEGIN
SET @OrderBy = 'ProductName';
END
SELECT TOP (@RecordLimit)
sv.ClientID,
sv.VendorID,
sv.ProductID,
sv.TransactionTime,
sv.ClientName,
sv.VendorName,
sv.ProductName,
sv.ProductCode,
sv.VendorCode,
FROM SortedReportiew AS sv
WHERE (sv.ClientID = @ClientID)
AND (sv.TransactionTime >= @FromDate)
AND (sv.TransactionTime < @Date)
更新
以下部分是否正确?来自here
的引用ORDER BY
CASE @OrderBy WHEN 'ProductCode ASC' THEN ProductCode WHEN 'ProductCode DESC' THEN ProductCode END DESC,
CASE @OrderBy WHEN 'ProductName ASC' THEN ProductName WHEN 'ProductName DESC' THEN ProductName END DESC,
答案 0 :(得分:12)
正如您所说:使用ORDER BY CASE
,但多次使用以避免不同列类型的问题:
...
ORDER BY
CASE WHEN @OrderBy ='ProductName ASC' THEN sv.ProductName END,
CASE WHEN @OrderBy ='ProductName DESC' THEN sv.ProductName END DESC,
CASE WHEN @OrderBy ='ProductCode ASC' THEN sv.ProductCode END,
CASE WHEN @OrderBy ='ProductCode DESC' THEN sv.ProductCode END DESC,
CASE WHEN @OrderBy ='VendorName ASC' THEN sv.VendorName END,
CASE WHEN @OrderBy ='VendorName DESC' THEN sv.VendorName END DESC,
CASE WHEN @OrderBy ='VendorCode' THEN sv.VendorCode END,
CASE WHEN @OrderBy ='ClientName' THEN sv.ClientName END
修改强>
更新了查询以适应您更新的问题。我假设您的意思是ProductCode ASC
和 ProductCode DESC
?
答案 1 :(得分:3)
据我所知,订购仅使用一列。在这种情况下,我可能会尝试这样的事情:
将@OrderBy
拆分为@OrderByCol
和@OrderByDir
。
使用此模板:
...
ORDER BY
CASE @OrderByDir WHEN 'ASC' THEN
CASE @OrderByCol
WHEN 'Column1' THEN Column1
WHEN 'Column2' THEN Column2
...
END
END ASC,
CASE @OrderByDir WHEN 'DESC' THEN
CASE @OrderByCol
WHEN 'Column1' THEN Column1
WHEN 'Column2' THEN Column2
...
END
END DESC
或者,如果您使用的是SQL Server 2005+,也许还有这个,作为替代方案:
WITH sorted AS (
SELECT
... /* columns, omitted */
Column1Order = ROW_NUMBER() OVER (ORDER BY Column1),
Column2Order = ROW_NUMBER() OVER (ORDER BY Column2),
...
FROM ...
)
SELECT ...
FROM sorted
ORDER BY
CASE @OrderByCol
WHEN 'Column1' THEN Column1Order
WHEN 'Column2' THEN Column2Order
...
END * CASE @OrderByDir WHEN 'DESC' THEN -1 ELSE 1 END
正如@Greg Ogle在评论中正确指出的那样,第一个模板只能在各种排序条件属于兼容类型时才能工作,否则语句就会中断。