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