sql >> Databasteknik >  >> RDS >> Sqlserver

T-SQL villkorlig beställning av

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



  1. hur väljer man jämna poster från en tabell i Oracle?

  2. Hur man exporterar en lista med länkade tabeller till Excel från Access 2016

  3. Hur man kör och konfigurerar ProxySQL 2.0 för MySQL Galera Cluster på Docker

  4. Hur använder man MySQLDB SScursor effektivt?