CASE
is een expressie die een waarde retourneert. Het is niet voor controle van de stroom, zoals IF
. En je kunt IF
. niet gebruiken binnen een zoekopdracht.
Helaas zijn er enkele beperkingen met CASE
uitdrukkingen die het lastig maken om te doen wat je wilt. Bijvoorbeeld alle takken in een CASE
expressie moet hetzelfde type retourneren of impliciet converteerbaar zijn naar hetzelfde type. Ik zou dat niet proberen met snaren en datums. U kunt CASE
ook niet gebruiken om de sorteerrichting op te geven.
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;
Een aantoonbaar eenvoudigere oplossing (vooral als dit complexer wordt) is om dynamische SQL te gebruiken. Om SQL-injectie te voorkomen, kunt u de waarden testen:
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;
Nog een pluspunt van dynamische SQL, ondanks alle angstzaaierij die erover wordt verspreid:je kunt het beste plan krijgen voor elke soortvariatie, in plaats van één enkel plan dat zal optimaliseren voor de soortvariatie die je als eerste hebt gebruikt. Het presteerde ook universeel het beste in een recente prestatievergelijking die ik uitvoerde:
http://sqlperformance.com/conditional-order-by