I've the following MS SQL stored procedure. I need to sort the results without using dynamic SQL and sp_executesql
method
@Order by can have the possible values ProductName ASC
, ProductName DESC
, ProductCode ASC
, VendorName DESC
, VendorCode
or ClientName
I was trying to use ORDER BY CASE
, is there any issue if the ProductName
, ProductCode
are of different type?
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)
Update:
Is the below part correct? ref from 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,
Of course, we can certainly hard-code the ORDER BY clause in a stored procedure, but this approach becomes fixed in stone. We could try a dynamic SQL solution, involving a stored procedure code that dynamically builds and executes SQL Server statements inside a stored procedure.
The ORDER BY statement in SQL is used to sort the fetched data in either ascending or descending according to one or more columns. By default ORDER BY sorts the data in ascending order. We can use the keyword DESC to sort the data in descending order and the keyword ASC to sort in ascending order.
ORDER BY Characteristics: The ORDER BY clause is used to get the sorted records on one or more columns in ascending or descending order. The ORDER BY clause must come after the WHERE, GROUP BY, and HAVING clause if present in the query. Use ASC or DESC to specify the sorting order after the column name.
Yes, you can order by a field(s)even if it is not your in your select statement but exists in your table. For a group by clause though you'd need it to be in your select statement. There's another exception, when you're using SELECT DISTINCT you must include the fields used in the GROUP BY clause in the select list.
As you already said: Use ORDER BY CASE
, but multiple times to avoid the problems with different column types:
...
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
EDIT:
Updated the query to fit your updated question. I assume you meant ProductCode ASC
and ProductCode DESC
?
I understand, the ordering uses just one column. In that case I might try something like this:
Split @OrderBy
into @OrderByCol
and @OrderByDir
.
Use this template:
...
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
Or, if you are on SQL Server 2005+, maybe this one, as an alternative:
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
As @Greg Ogle has correctly pointed out in the comment, the first template can only work when the various sorting criteria are of compatible types, otherwise the statement will break.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With