CASE
är ett uttryck som returnerar ett värde. Det är inte för kontroll av flödet, som IF
. Och du kan inte använda IF
i en fråga.
Tyvärr finns det vissa begränsningar med CASE
uttryck som gör det krångligt att göra vad man vill. Till exempel alla grenar i en CASE
uttryck måste returnera samma typ eller vara implicit konverterbart till samma typ. Jag skulle inte prova det där med snören och datum. Du kan inte heller använda CASE
för att ange sorteringsriktning.
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 utan tvekan enklare lösning (speciellt om detta blir mer komplext) är att använda dynamisk SQL. För att förhindra SQL-injektion kan du testa värdena:
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;
Ett annat plus för dynamisk SQL, trots all rädsla som sprids om det:du kan få den bästa planen för varje sortsvariation, istället för en enda plan som kommer att optimera till vilken sortsvariation du råkade använda först. Den presterade också bäst allmänt i en nyligen prestandajämförelse jag körde:
http://sqlperformance.com/conditional-order-by