CASE
er et udtryk, der returnerer en værdi. Det er ikke til kontrol af flow, som IF
. Og du kan ikke bruge IF
i en forespørgsel.
Desværre er der nogle begrænsninger med CASE
udtryk, der gør det besværligt at gøre, hvad man vil. For eksempel alle grenene i en CASE
udtryk skal returnere den samme type eller være implicit konverterbar til den samme type. Jeg ville ikke prøve det med strenge og dadler. Du kan heller ikke bruge CASE
for at angive sorteringsretning.
SELECT column_list_please
FROM dbo.Product -- dbo prefix please
ORDER BY
CASE WHEN @sortDir = 'asc' AND @sortOrder = 'name' THEN name END,
CASE WHEN @sortDir = 'asc' AND @sortOrder = 'created_date' THEN created_date END,
CASE WHEN @sortDir = 'desc' AND @sortOrder = 'name' THEN name END DESC,
CASE WHEN @sortDir = 'desc' AND @sortOrder = 'created_date' THEN created_date END DESC;
En uden tvivl nemmere løsning (især hvis dette bliver mere komplekst) er at bruge dynamisk SQL. For at forhindre SQL-injektion kan du teste værdierne:
IF @sortDir NOT IN ('asc', 'desc')
OR @sortOrder NOT IN ('name', 'created_date')
BEGIN
RAISERROR('Invalid params', 11, 1);
RETURN;
END
DECLARE @sql NVARCHAR(MAX) = N'SELECT column_list_please
FROM dbo.Product ORDER BY ' + @sortOrder + ' ' + @sortDir;
EXEC sp_executesql @sql;
Et andet plus for dynamisk SQL, på trods af al den frygt-manger, der spredes om det:du kan få den bedste plan for hver sorteringsvariation, i stedet for én enkelt plan, der vil optimere til den slags variant, du tilfældigvis brugte først. Den klarede sig også bedst universelt i en nylig præstationssammenligning, jeg kørte:
http://sqlperformance.com/conditional-order-by