sql >> Database teknologi >  >> RDS >> Sqlserver

T-SQL betinget bestilling af

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



  1. Sådan kombinerer du resultaterne af to forespørgsler i SQL

  2. Sådan sikrer du dig, at din MySQL-database er sikret

  3. FEJL:Relationssteder findes ikke Heroku db import

  4. oracle hurtigere personsøgningsforespørgsel