sql - attribute - Dirección de orden dinámica
title html (5)
Escribo un SP que acepta como columna de parámetros para ordenar y dirección.
No quiero usar SQL dinámico.
El problema es con la configuración del parámetro de dirección.
Este es el código parcial:
SET @OrderByColumn = ''AddedDate''
SET @OrderDirection = 1;
…
ORDER BY
CASE WHEN @OrderByColumn = ''AddedDate'' THEN CONVERT(varchar(50), AddedDate)
WHEN @OrderByColumn = ''Visible'' THEN CONVERT(varchar(2), Visible)
WHEN @OrderByColumn = ''AddedBy'' THEN AddedBy
WHEN @OrderByColumn = ''Title'' THEN Title
END
Aquí hay un ejemplo:
CREATE PROCEDURE GetProducts
(
@OrderBy VARCHAR(50),
@Input2 VARCHAR(30)
)
AS
BEGIN
SET NOCOUNT ON
SELECT Id, ProductName, Description, Price, Quantity
FROM Products
WHERE ProductName LIKE @Input2
ORDER BY
CASE
WHEN @OrderBy = ''ProductNameAsc'' THEN ProductName
END ASC,
CASE
WHEN @OrderBy = ''ProductNameDesc'' THEN ProductName
END DESC
END
De aquí:
http://www.dominicpettifer.co.uk/Blog/21/dynamic-conditional-order-by-clause-in-sql-server-t-sql
Las acciones ascendentes y descendentes deben agruparse en declaraciones CASE separadas, separadas por una coma. En su código / script del lado del servidor, asegúrese de agregar ''Asc'' o ''Desc'' al orden por cadena, o puede tener dos parámetros de entrada de procedimiento Almacenado para el nombre de la columna y ordenar por dirección si lo desea.
Esto funciona bien para mí - ( where
, order by
, direction
, Pagination
)
parameters
@orderColumn int ,
@orderDir varchar(20),
@start int ,
@limit int
select * from items
WHERE (items.status = 1)
order by
CASE WHEN @orderColumn = 0 AND @orderdir = ''desc'' THEN items.[category] END DESC,
CASE WHEN @orderColumn = 0 AND @orderdir = ''asc'' THEN items.[category] END ASC,
CASE WHEN @orderColumn = 1 AND @orderdir = ''desc'' THEN items.[category] END DESC,
CASE WHEN @orderColumn = 1 AND @orderdir = ''asc'' THEN items.[category] END ASC,
CASE WHEN @orderColumn = 2 AND @orderdir = ''desc'' THEN items.[category] END DESC,
CASE WHEN @orderColumn = 2 AND @orderdir = ''asc'' THEN items.[category] END ASC
OFFSET @start ROWS FETCH NEXT @limit ROWS ONLY
Podría tener dos artículos ORDER BY
casi idénticos, un ASC
y un DESC
, y extender su declaración CASE
para hacer que uno u otro de ellos siempre sea igual a un valor único:
ORDER BY
CASE WHEN @OrderDirection = 0 THEN 1
ELSE
CASE WHEN @OrderByColumn = ''AddedDate'' THEN CONVERT(varchar(50), AddedDate)
WHEN @OrderByColumn = ''Visible'' THEN CONVERT(varchar(2), Visible)
WHEN @OrderByColumn = ''AddedBy'' THEN AddedBy
WHEN @OrderByColumn = ''Title'' THEN Title
END
END ASC,
CASE WHEN @OrderDirection = 1 THEN 1
ELSE
CASE WHEN @OrderByColumn = ''AddedDate'' THEN CONVERT(varchar(50), AddedDate)
WHEN @OrderByColumn = ''Visible'' THEN CONVERT(varchar(2), Visible)
WHEN @OrderByColumn = ''AddedBy'' THEN AddedBy
WHEN @OrderByColumn = ''Title'' THEN Title
END
END DESC
Puede simplificar el CASO utilizando ROW_NUMBER que ordena sus datos y los convierte efectivamente en un formato entero útil. Especialmente porque la pregunta está etiquetada SQL Server 2005
Esto también se expande con la suficiente facilidad para lidiar con géneros secundarios y terciarios
Utilicé el multiplicador para simplificar de nuevo la declaración de selección real y reducir la posibilidad de evaluación RBAR en el ORDER BY
DECLARE @multiplier int;
SELECT @multiplier = CASE @Direction WHEN 1 THEN -1 ELSE 1 END;
SELECT
Columns you actually want
FROM
(
SELECT
Columns you actually want,
ROW_NUMBER() OVER (ORDER BY AddedDate) AS AddedDateSort,
ROW_NUMBER() OVER (ORDER BY Visible) AS VisibleSort,
ROW_NUMBER() OVER (ORDER BY AddedBy) AS AddedBySort,
ROW_NUMBER() OVER (ORDER BY Title) AS TitleSort
FROM
myTable
WHERE
MyFilters...
) foo
ORDER BY
CASE @OrderByColumn
WHEN ''AddedDate'' THEN AddedDateSort
WHEN ''Visible'' THEN VisibleSort
WHEN ''AddedBy'' THEN AddedBySort
WHEN ''Title'' THEN TitleSort
END * @multiplier;
Versión más compacta de la answer aceptada, pero como respuesta aceptada, esto funciona bien solo cuando las expresiones de resultado después de THEN
tienen el mismo tipo.
ORDER BY
CASE @OrderDirection WHEN 0 THEN
CASE @sortColumn
WHEN ''AddedDate'' THEN CONVERT(varchar(50), AddedDate)
WHEN ''Visible'' THEN CONVERT(varchar(2), Visible)
WHEN ''AddedBy'' THEN AddedBy
WHEN ''Title'' THEN Title
END
END ASC,
CASE @OrderDirection WHEN 1 THEN
CASE @sortColumn
WHEN ''AddedDate'' THEN CONVERT(varchar(50), AddedDate)
WHEN ''Visible'' THEN CONVERT(varchar(2), Visible)
WHEN ''AddedBy'' THEN AddedBy
WHEN ''Title'' THEN Title
END
END DESC