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
War es hilfreich?

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

reduzieren
DECLARE @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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top