Direction dynamique des commandes

j'écris un SP qui accepte comme colonne de paramètres le tri et la direction.

Je ne veux pas utiliser le SQL dynamique.

le problème est de définir le paramètre de direction.

C'est le code partiel:

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
23
demandé sur Vadim Ovchinnikov 2009-07-18 19:10:00
la source

5 ответов

vous pourriez avoir deux ORDER BY presque identiques articles, un ASC et un DESC , et d'étendre votre CASE déclaration pour faire l'un ou l'autre d'entre eux égale toujours une seule valeur:

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
29
répondu Gary McGill 2018-05-11 15:13:01
la source

vous pouvez simplifier le cas en utilisant ROW_NUMBER qui trie vos données et les convertit efficacement dans un format de nombre entier pratique. D'autant plus que la question Est tagged SQL Server 2005

cela s'étend aussi assez facilement pour traiter avec des sortes secondaires et tertiaires

j'ai utilisé le multiplicateur pour simplifier à nouveau la déclaration select réelle et réduire la chance de L'évaluation RBAR dans l'ordre de

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;
12
répondu gbn 2009-07-18 21:19:58
la source

voici un exemple:

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

D'ici:

http://www.dominicpettifer.co.uk/Blog/21/dynamic-conditional-order-by-clause-in-sql-server-t-sql

actions ascendantes et descendantes à regrouper dans un dossier distinct états, séparés par une virgule. Dans votre code/script côté serveur Assurez-vous pour ajouter 'Asc' ou 'Desc' sur le ordre par ficelle, ou vous pourrait avoir deux Procédure stockée paramètres d'entrée pour nom de la colonne et ordre Par ordre si vous voulez.

3
répondu Alex Black 2009-07-18 19:23:33
la source

ça me va très bien.– ( 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
2
répondu Arun Prasad E S 2018-05-11 17:28:52
la source

version plus compacte de réponse , mais comme réponse acceptée cela ne fonctionne bien que lorsque les expressions de résultat après THEN ont le même type.

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
1
répondu Vadim Ovchinnikov 2018-05-16 05:05:48
la source