Cas SQL avec 2 conditions

J'ai une procédure stockée qui acceptera 2 parameters différents. Le premier paramètre déterminera quelle colonne je veux sortinger, le second paramètre déterminera si c'est ASC ou DESC

 Create Procedure Some_SP @sortcolumn varchar(10) @sortorder varchar(10) AS Select * from empTable Order by CASE @sortcolumn WHEN 'First_Name' THEN fname END, CASE @sortcolumn WHEN 'Last_Name' THEN lname END, CASE @sortcolumn WHEN 'ID' THEN empID END, CASE @sortorder WHEN 'ascending' THEN ASC END, CASE @sortorder WHEN 'descending' THEN DESC END 

Cela me donne une erreur de syntaxe. Comment puis-je résoudre ce problème pour que je puisse avoir 2 conditions dans ma déclaration CASE?

Ce qui suit fonctionnera:

 Select * from empTable Order by CASE WHEN @sortcolumn = 'First_Name' AND @SortOrder = 'ascending' THEN fname END ASC, CASE WHEN @sortcolumn = 'First_Name' AND @SortOrder = 'descending' THEN fname END DESC 

etc…

Afin d'éviter de taper à la main chacune de ces instructions, vous pouvez écrire un script "generator" que vous utilisez pour créer ceci (particulièrement bon si la définition de la table change):

 SELECT 'CASE WHEN @SortColumn = ''' + C.name + ''' AND @SortOrder = ''ascending'' THEN ' + C.name + ' END ASC,' + CHAR(13) + CHAR(10) + 'CASE WHEN @SortColumn = ''' + C.name + ''' AND @SortOrder = ''descending'' THEN ' + C.name + ' END DESC,' FROM sys.columns C WHERE C.object_id = object_id('[Schema].[Table]') 

Si vous voulez éviter le SQL dynamic et utiliser 2x vos conditions, vous pouvez utiliser row_number

par exemple:

 declare @t table (ssortingng varchar(50), number int) insert @t values ('a',9),('f',2),('c',1) declare @sc varchar(10) = 'number', -- or 'ssortingng', etc @so varchar(10) = 'desc' -- or 'asc' select * from ( select *, case @sc when 'ssortingng' then ROW_NUMBER() over (order by ssortingng) when 'number' then ROW_NUMBER() over (order by number) end rn from @t ) v order by case @so when 'desc' then -rn else rn end 

Vous pouvez simplement copyr et coller et exécuter ceci. Je déteste le SQL dynamic, ne le fais pas.

Malheureusement, vous devrez dupliquer la requête …. mais cela résout votre problème spécifique.

 DECLARE @sortcolumn varchar(10), @sortorder varchar(10) SET @sortcolumn = 'fname' SET @sortorder = 'DESC' DECLARE @Data TABLE ( fname nvarchar(10), lname nvarchar(10), empID int ) INSERT INTO @Data VALUES ('BBB', 'BBB', 2) INSERT INTO @Data VALUES ('AAA', 'AAA', 1) IF @sortorder = 'DESC' BEGIN SELECT * FROM @Data ORDER BY CASE WHEN @sortcolumn = 'fname' THEN fname WHEN @sortcolumn = 'lname' THEN lname END DESC END ELSE BEGIN SELECT * FROM @Data ORDER BY CASE WHEN @sortcolumn = 'fname' THEN fname WHEN @sortcolumn = 'lname' THEN lname END END 

Modification de la réponse de Jon pour fermer la list ORDER BY à 2 au lieu de 2 * #columns

 SELECT * FROM MyTable CROSS APPLY (VALUES ('First_Name',fname), ('Last_Name' ,lname), ('Id' ,ID ) ) sort(SortColumn, SortValue) WHERE SortColumn = @SortColumn ORDER BY CASE @SortOrder WHEN 'ascending' THEN SortValue END ASC, CASE @SortOrder WHEN 'descending' THEN SortValue END DESC