CASE
ist ein Ausdruck, der einen Wert zurückgibt. Es dient nicht der Flusskontrolle, wie IF
. Und Sie können IF
nicht verwenden innerhalb einer Abfrage.
Leider gibt es einige Einschränkungen bei CASE
Ausdrücke, die es umständlich machen, das zu tun, was Sie wollen. Zum Beispiel alle Zweige in einem CASE
Ausdruck muss denselben Typ zurückgeben oder implizit in denselben Typ konvertierbar sein. Ich würde das nicht mit Strings und Dates versuchen. Sie können auch nicht CASE
verwenden um die Sortierrichtung anzugeben.
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;
Eine wohl einfachere Lösung (insbesondere wenn dies komplexer wird) ist die Verwendung von dynamischem SQL. Um die SQL-Injection zu vereiteln, können Sie die Werte 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;
Ein weiteres Plus für dynamisches SQL, trotz aller Angstmacherei, die darüber verbreitet wird:Sie können den besten Plan für jede Sortiervariante erhalten, anstatt einen einzigen Plan, der auf die Sortiervariante optimiert, die Sie zufällig zuerst verwendet haben. Es hat auch in einem kürzlich von mir durchgeführten Leistungsvergleich am besten abgeschnitten:
http://sqlperformance.com/conditional-order-by