Dynamische Auftragsrichtung
-
18-09-2019 - |
Frage
Schreibe ich einen SP, die als Parameter Spalte akzeptiert zu sortieren und Richtung.
Ich will nicht, dynamische SQL verwenden.
Das Problem ist mit der Richtung Parametereinstellung.
Dies ist der Teil-Code:
SET @OrderByColumn = 'AddedDate'
SET @OrderDirection = 1;
…
ORDER BY
CASE WHEN @OrderByColumn = 'AddedDate' THEN CONVERT(varchar(50), AddedDate)
WHEN @OrderByColumn = 'Visible' THEN CONVERT(varchar(2), Visible)
WHEN @OrderByColumn = 'AddedBy' THEN AddedBy
WHEN @OrderByColumn = 'Title' THEN Title
END
Lösung
Sie konnten zwei nahezu identische ORDER BY
Einzelteile haben, eine ASC
und eine DESC
und Ihre CASE
Aussage erweitern die eine oder andere von ihnen immer einen einzelnen Wert gleich zu machen:
ORDER BY
CASE WHEN @OrderDirection = 0 THEN 1
ELSE
CASE WHEN @OrderByColumn = 'AddedDate' THEN CONVERT(varchar(50), AddedDate)
WHEN @OrderByColumn = 'Visible' THEN CONVERT(varchar(2), Visible)
WHEN @OrderByColumn = 'AddedBy' THEN AddedBy
WHEN @OrderByColumn = 'Title' THEN Title
END
END ASC,
CASE WHEN @OrderDirection = 1 THEN 1
ELSE
CASE WHEN @OrderByColumn = 'AddedDate' THEN CONVERT(varchar(50), AddedDate)
WHEN @OrderByColumn = 'Visible' THEN CONVERT(varchar(2), Visible)
WHEN @OrderByColumn = 'AddedBy' THEN AddedBy
WHEN @OrderByColumn = 'Title' THEN Title
END
END DESC
Andere Tipps
Sie können die CASE vereinfachen, indem ROW_NUMBER die Ihre Daten sortiert und effektiv wandelt es in ein handliches Integer-Format. Vor allem, da die Frage markiert SQL Server 2005
Dies ist auch leicht genug erweitert mit sekundären und tertiären Arten behandeln
Ich habe Multiplikator verwendet, um wieder die tatsächliche Select-Anweisung zu vereinfachen und die Chance RBAR Auswertung in der ORDER BY
reduzierenDECLARE @multiplier int;
SELECT @multiplier = CASE @Direction WHEN 1 THEN -1 ELSE 1 END;
SELECT
Columns you actually want
FROM
(
SELECT
Columns you actually want,
ROW_NUMBER() OVER (ORDER BY AddedDate) AS AddedDateSort,
ROW_NUMBER() OVER (ORDER BY Visible) AS VisibleSort,
ROW_NUMBER() OVER (ORDER BY AddedBy) AS AddedBySort,
ROW_NUMBER() OVER (ORDER BY Title) AS TitleSort
FROM
myTable
WHERE
MyFilters...
) foo
ORDER BY
CASE @OrderByColumn
WHEN 'AddedDate' THEN AddedDateSort
WHEN 'Visible' THEN VisibleSort
WHEN 'AddedBy' THEN AddedBySort
WHEN 'Title' THEN TitleSort
END * @multiplier;
Hier ist ein Beispiel:
CREATE PROCEDURE GetProducts
(
@OrderBy VARCHAR(50),
@Input2 VARCHAR(30)
)
AS
BEGIN
SET NOCOUNT ON
SELECT Id, ProductName, Description, Price, Quantity
FROM Products
WHERE ProductName LIKE @Input2
ORDER BY
CASE
WHEN @OrderBy = 'ProductNameAsc' THEN ProductName
END ASC,
CASE
WHEN @OrderBy = 'ProductNameDesc' THEN ProductName
END DESC
END
Von hier:
http://www.dominicpettifer.co.uk/Blog/21/dynamic-conditional-order-by-clause-in-sql-server-t-sql
aufsteigende und absteigende Aktionen müssen gruppiert in separate CASE werden Aussagen, mit einem Komma getrennt. Im Ihre serverseitigen Code / script stellen Sie sicher, ‚Asc‘ oder ‚Desc‘ auf den anhängen bestellen von string, oder Sie können zwei haben Stored Procedure Eingangsparameter für Spaltenname und Reihenfolge von Richtung, wenn Sie wollen.
Dies funktioniert gut für mich - (where
, order by
, direction
, Pagination
)
parameters
@orderColumn int ,
@orderDir varchar(20),
@start int ,
@limit int
select * from items
WHERE (items.status = 1)
order by
CASE WHEN @orderColumn = 0 AND @orderdir = 'desc' THEN items.[category] END DESC,
CASE WHEN @orderColumn = 0 AND @orderdir = 'asc' THEN items.[category] END ASC,
CASE WHEN @orderColumn = 1 AND @orderdir = 'desc' THEN items.[category] END DESC,
CASE WHEN @orderColumn = 1 AND @orderdir = 'asc' THEN items.[category] END ASC,
CASE WHEN @orderColumn = 2 AND @orderdir = 'desc' THEN items.[category] END DESC,
CASE WHEN @orderColumn = 2 AND @orderdir = 'asc' THEN items.[category] END ASC
OFFSET @start ROWS FETCH NEXT @limit ROWS ONLY
kompaktere Version der akzeptierten beantworten , aber als Antwort akzeptiert dies funktioniert nur gut, wenn Ergebnis Ausdrücke nach THEN
die gleiche haben Art.
ORDER BY
CASE @OrderDirection WHEN 0 THEN
CASE @sortColumn
WHEN 'AddedDate' THEN CONVERT(varchar(50), AddedDate)
WHEN 'Visible' THEN CONVERT(varchar(2), Visible)
WHEN 'AddedBy' THEN AddedBy
WHEN 'Title' THEN Title
END
END ASC,
CASE @OrderDirection WHEN 1 THEN
CASE @sortColumn
WHEN 'AddedDate' THEN CONVERT(varchar(50), AddedDate)
WHEN 'Visible' THEN CONVERT(varchar(2), Visible)
WHEN 'AddedBy' THEN AddedBy
WHEN 'Title' THEN Title
END
END DESC