dates attribute sql sql-server stored-procedures sql-order-by case

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