Clasificación dinámica dentro de procedimientos almacenados de SQL

126

Este es un problema que he pasado horas investigando en el pasado. Me parece algo que debería haber sido abordado por las soluciones RDBMS modernas , pero hasta ahora no he encontrado nada que realmente aborde lo que veo como una necesidad increíblemente común en cualquier aplicación web o Windows con una base de datos.

Hablo de ordenación dinámica. En mi mundo de fantasía, debería ser tan simple como algo como:

ORDER BY @sortCol1, @sortCol2

Este es el ejemplo canónico dado por los novatos desarrolladores de SQL y procedimientos almacenados en todos los foros de Internet. "¿Por qué no es esto posible?" ellos preguntan. Invariablemente, eventualmente alguien viene a darles una conferencia sobre la naturaleza compilada de los procedimientos almacenados, de los planes de ejecución en general, y todo tipo de otras razones por las cuales no es posible poner un parámetro directamente en una ORDER BYcláusula.


Sé lo que algunos de ustedes ya están pensando: "Deje que el cliente haga la clasificación, entonces". Naturalmente, esto descarga el trabajo de su base de datos. Sin embargo, en nuestro caso, nuestros servidores de bases de datos ni siquiera están sudando el 99% del tiempo y ni siquiera son multinúcleo ni ninguna de las otras miles de mejoras en la arquitectura del sistema que ocurren cada 6 meses. Solo por esta razón, hacer que nuestras bases de datos manejen la clasificación no sería un problema. Además, las bases de datos son muybueno en la clasificación Están optimizados para ello y han tenido años para hacerlo bien, el lenguaje para hacerlo es increíblemente flexible, intuitivo y simple y, sobre todo, cualquier escritor principiante de SQL sabe cómo hacerlo y, lo que es más importante, saben cómo editarlo, realizar cambios, realizar tareas de mantenimiento, etc. Cuando sus bases de datos están lejos de estar sujetas a impuestos y solo desea simplificar (¡y acortar!) el tiempo de desarrollo, esto parece una opción obvia.

Luego está el problema web. He jugado con JavaScript que hará la clasificación del lado del cliente de las tablas HTML, pero inevitablemente no son lo suficientemente flexibles para mis necesidades y, una vez más, dado que mis bases de datos no están excesivamente gravadas y pueden hacer la clasificación de manera muy fácil, me resulta difícil justificar el tiempo que llevaría volver a escribir o clasificar mi propio clasificador de JavaScript. Lo mismo ocurre generalmente con la ordenación del lado del servidor, aunque probablemente ya sea mucho más preferido que JavaScript. No soy uno que le guste particularmente los gastos generales de los DataSets, así que demándame.

Pero esto trae de vuelta el punto de que no es posible, o más bien, no es fácil. He hecho, con sistemas anteriores, una forma increíblemente hack de obtener una clasificación dinámica. No era bonito, ni intuitivo, simple o flexible, y un escritor principiante de SQL se perdería en segundos. Ya parece que esto no es tanto una "solución" sino una "complicación".


Los siguientes ejemplos no están destinados a exponer ningún tipo de mejores prácticas o buen estilo de codificación ni nada, ni son indicativos de mis habilidades como programador de T-SQL. Son lo que son y admito que son confusos, de mala forma y simplemente piratas.

Pasamos un valor entero como parámetro a un procedimiento almacenado (llamemos al parámetro simplemente "ordenar") y a partir de eso determinamos un montón de otras variables. Por ejemplo ... digamos que sort es 1 (o el valor predeterminado):

DECLARE @sortCol1 AS varchar(20)
DECLARE @sortCol2 AS varchar(20)
DECLARE @dir1 AS varchar(20)
DECLARE @dir2 AS varchar(20)
DECLARE @col1 AS varchar(20)
DECLARE @col2 AS varchar(20)

SET @col1 = 'storagedatetime';
SET @col2 = 'vehicleid';

IF @sort = 1                -- Default sort.
BEGIN
    SET @sortCol1 = @col1;
    SET @dir1 = 'asc';
    SET @sortCol2 = @col2;
    SET @dir2 = 'asc';
END
ELSE IF @sort = 2           -- Reversed order default sort.
BEGIN
    SET @sortCol1 = @col1;
    SET @dir1 = 'desc';
    SET @sortCol2 = @col2;
    SET @dir2 = 'desc';
END

Ya puede ver cómo si declarara más variables @colX para definir otras columnas, realmente podría ser creativo con las columnas para ordenar en función del valor de "ordenar" ... para usarlo, generalmente termina pareciéndose a lo siguiente cláusula increíblemente desordenada:

ORDER BY
    CASE @dir1
        WHEN 'desc' THEN
            CASE @sortCol1
                WHEN @col1 THEN [storagedatetime]
                WHEN @col2 THEN [vehicleid]
            END
    END DESC,
    CASE @dir1
        WHEN 'asc' THEN
            CASE @sortCol1
                WHEN @col1 THEN [storagedatetime]
                WHEN @col2 THEN [vehicleid]
            END
    END,
    CASE @dir2
        WHEN 'desc' THEN
            CASE @sortCol2
                WHEN @col1 THEN [storagedatetime]
                WHEN @col2 THEN [vehicleid]
            END
    END DESC,
    CASE @dir2
        WHEN 'asc' THEN
            CASE @sortCol2
                WHEN @col1 THEN [storagedatetime]
                WHEN @col2 THEN [vehicleid]
            END
    END

Obviamente este es un ejemplo muy despojado. Lo real, ya que generalmente tenemos cuatro o cinco columnas para admitir la clasificación, cada una con una posible secundaria o incluso una tercera columna para clasificar además de eso (por ejemplo, fecha descendente y luego ordenada secundariamente por nombre ascendente) y cada una clasificación direccional que efectivamente duplica el número de casos. Sí ... se pone peludo muy rápido.

La idea es que uno podría "cambiar fácilmente" los casos de clasificación de manera que el vehículo se clasifique antes del tiempo de almacenamiento ... pero la pseudo-flexibilidad, al menos en este simple ejemplo, realmente termina allí. Esencialmente, cada caso que falla una prueba (porque nuestro método de clasificación no se aplica esta vez) presenta un valor NULL. Y así terminas con una cláusula que funciona como la siguiente:

ORDER BY NULL DESC, NULL, [storagedatetime] DESC, blah blah

Tienes la idea. Funciona porque SQL Server ignora efectivamente los valores nulos en orden por cláusulas. Esto es increíblemente difícil de mantener, como puede ver cualquier persona con conocimientos básicos de SQL. Si los he perdido, no se sienta mal. Nos llevó mucho tiempo hacerlo funcionar y todavía nos confundimos al intentar editarlo o crear otros nuevos como este. Afortunadamente, no es necesario cambiarlo con frecuencia, de lo contrario se convertiría rápidamente en "no vale la pena".

Sin embargo , funcionó.


Mi pregunta es entonces: ¿hay una mejor manera?

Estoy de acuerdo con otras soluciones que no sean las de Procedimiento almacenado, ya que me doy cuenta de que puede que no sea el camino a seguir. Preferiblemente, me gustaría saber si alguien puede hacerlo mejor dentro del Procedimiento almacenado, pero si no es así, ¿cómo se maneja permitiendo que el usuario ordene dinámicamente tablas de datos (también bidireccionalmente) con ASP.NET?

¡Y gracias por leer (o al menos descremar) una pregunta tan larga!

PD: Alégrate de no haber mostrado mi ejemplo de un procedimiento almacenado que admite la ordenación dinámica, el filtrado dinámico / la búsqueda de texto de columnas, la paginación a través de ROWNUMBER () OVER, y prueba ... atrapar con la reversión de transacciones en errores ... "tamaño gigante" ni siquiera comienza a describirlos.


Actualizar:

  • Me gustaría evitar el SQL dinámico . Analizar una cadena y ejecutar un EXEC en ella anula mucho el propósito de tener un procedimiento almacenado en primer lugar. Sin embargo, a veces me pregunto si los inconvenientes de hacer algo así no valdrían la pena, al menos en estos casos especiales de clasificación dinámica. Aún así, siempre me siento sucio cada vez que hago cadenas SQL dinámicas como esa, como si aún viviera en el mundo ASP clásico.
  • Gran parte de la razón por la que queremos procedimientos almacenados en primer lugar es por seguridad . No puedo hacer una llamada por cuestiones de seguridad, solo sugerir soluciones. Con SQL Server 2005 podemos establecer permisos (por usuario si es necesario) a nivel de esquema en procedimientos almacenados individuales y luego denegar cualquier consulta directamente en las tablas. Criticar los pros y los contras de este enfoque es quizás para otra pregunta, pero nuevamente no es mi decisión. Solo soy el mono código principal. :)
Sean Hanley
fuente
Consulte stackoverflow.com/questions/3659981/… también - SQL Server dinámico ORDER BY con tipos de datos mixtos
LCJ
El SQL dinámico es la forma MUY superior ... IF [y este es un gran IF] ... su capa de acceso a datos es estricta y su SQL dinámico es generado por un sistema que está rígidamente programado con reglas RDBMS expresadas en forma perfecta. Una arquitectura de base de datos de ingeniería algorítmica es una cosa
hermosa

Respuestas:

97

Sí, es un dolor, y la forma en que lo haces se parece a lo que hago:

order by
case when @SortExpr = 'CustomerName' and @SortDir = 'ASC' 
    then CustomerName end asc, 
case when @SortExpr = 'CustomerName' and @SortDir = 'DESC' 
    then CustomerName end desc,
...

Esto, para mí, sigue siendo mucho mejor que construir SQL dinámico a partir del código, lo que se convierte en una pesadilla de escalabilidad y mantenimiento para los DBA.

Lo que hago desde el código es refactorizar la paginación y la clasificación, por lo que al menos no tengo mucha repetición allí con los valores de relleno para @SortExpry @SortDir.

En lo que respecta al SQL, mantenga el diseño y el formato iguales entre los diferentes procedimientos almacenados, para que al menos sea ordenado y reconocible cuando realice cambios.

Eric Z Beard
fuente
1
Exactamente. Mi objetivo era evitar hacer un comando EXEC en una gran cadena 5000 varchar. Todo lo que hacemos debe hacerse a través de procedimientos almacenados, aunque solo sea por la seguridad adicional, ya que podemos establecer permisos en ellos a nivel de esquema. La escalabilidad y las ganancias de rendimiento son solo una ventaja en nuestro caso.
Sean Hanley
1
Agregue mantenibilidad a {seguridad, escalabilidad, rendimiento}. Una vez que tiene 3 o 4 aplicaciones con SQL dinámico que se ejecuta contra su base de datos, está jodido, no puede cambiar nada, especialmente a medida que las aplicaciones envejecen y los desarrolladores continúan. Exec y sql dinámico son malvados.
Eric Z Beard
Eso es todo --- ya lo hacemos, desde mucho antes de llegar aquí, para todas las aplicaciones web Classic ASP que aún se ejecutan y muchas, muchas aplicaciones de Access VB que aún circulan. Me contraigo y tengo que contener los impulsos para corregir errores evidentes cada vez que tengo que realizar tareas de mantenimiento en alguno de ellos.
Sean Hanley
1
Esto es lo que hago también, excepto que codifico la dirección en SortExpr: ORDEN POR CASO CUANDO sort = 'FirstName' LUEGO FirstName END ASC, CASE WHEN sort = '-FirstName' THEN FirstName END DESC
Michael Bray
Esta es LA pesadilla para DBAs e ingenieros de software por igual. Entonces, en lugar de poder tener sistemas dinámicos pero estrictos que generen declaraciones SQL expresivas basadas en su esquema de información, tiene este asqueroso conjunto de galimatías codificadas. Es una programación pobre en su máxima expresión.
hajikelist
23

Este enfoque evita que las columnas ordenables se dupliquen dos veces en el orden, y es un poco más legible en mi opinión:

SELECT
  s.*
FROM
  (SELECT
    CASE @SortCol1
      WHEN 'Foo' THEN t.Foo
      WHEN 'Bar' THEN t.Bar
      ELSE null
    END as SortCol1,
    CASE @SortCol2
      WHEN 'Foo' THEN t.Foo
      WHEN 'Bar' THEN t.Bar
      ELSE null
    END as SortCol2,
    t.*
  FROM
    MyTable t) as s
ORDER BY
  CASE WHEN @dir1 = 'ASC'  THEN SortCol1 END ASC,
  CASE WHEN @dir1 = 'DESC' THEN SortCol1 END DESC,
  CASE WHEN @dir2 = 'ASC'  THEN SortCol2 END ASC,
  CASE WHEN @dir2 = 'DESC' THEN SortCol2 END DESC
Jason DeFontes
fuente
Esto parecía una buena respuesta, pero no parece funcionar cuando las columnas ordenables tienen diferentes tipos de datos
SlimSim
6

Mis aplicaciones hacen esto mucho, pero todas están construyendo dinámicamente el SQL. Sin embargo, cuando trato con procedimientos almacenados hago esto:

  1. Convierta el procedimiento almacenado en una función que devuelva una tabla de sus valores, sin ordenar.
  2. Luego, en el código de la aplicación, haga un select * from dbo.fn_myData() where ... order by ...para que pueda especificar dinámicamente el orden de clasificación allí.

Entonces, al menos, la parte dinámica está en su aplicación, pero la base de datos todavía está haciendo el trabajo pesado.

Ron salvaje
fuente
1
Ese es probablemente el mejor compromiso que he visto hasta ahora entre el uso de SQL dinámico y los procedimientos almacenados juntos. Me gusta. En algún momento podría experimentar con un enfoque similar, pero dicho cambio sería prohibitivo en cualquiera de nuestros proyectos en curso.
Sean Hanley
1
Puede lograr lo mismo utilizando una variable de tabla local en lugar de la función tabular que devuelve datos. Encuentro las tablas locales más flexibles que las funciones, ya que puede generar información de depuración.
Sanjay Zalke
5

Una técnica de procedimiento almacenado (¿pirateo?) Que he usado para evitar SQL dinámico para ciertos trabajos es tener una columna de clasificación única. Es decir,

SELECT
   name_last,
   name_first,
   CASE @sortCol WHEN 'name_last' THEN [name_last] ELSE 0 END as mySort
FROM
   table
ORDER BY 
    mySort

Este es fácil de superar en el envío: puede concatenar campos en su columna mySort, invertir el orden con funciones matemáticas o de fecha, etc.

Sin embargo, preferiblemente, uso mis vistas de cuadrícula asp.net u otros objetos con clasificación integrada para hacer la clasificación por mí DESPUÉS de recuperar los datos de Sql-Server. O incluso si no está integrado, por ejemplo, tablas de datos, etc. en asp.net.

Dave
fuente
4

Hay un par de formas diferentes en que puedes hackear esto.

Prerrequisitos:

  1. Solo una instrucción SELECT en el sp
  2. Deje de lado cualquier clasificación (o tenga un valor predeterminado)

Luego inserte en una tabla temporal:

create table #temp ( your columns )

insert #temp
exec foobar

select * from #temp order by whatever

Método # 2: configure un servidor vinculado de nuevo a sí mismo, luego seleccione de esto usando openquery: http://www.sommarskog.se/share_data.html#OPENQUERY

Matt Rogish
fuente
4

Puede haber una tercera opción, ya que su servidor tiene muchos ciclos de repuesto: use un procedimiento auxiliar para ordenar a través de una tabla temporal. Algo como

create procedure uspCallAndSort
(
    @sql varchar(2048),        --exec dbo.uspSomeProcedure arg1,'arg2',etc.
    @sortClause varchar(512)    --comma-delimited field list
)
AS
insert into #tmp EXEC(@sql)
declare @msql varchar(3000)
set @msql = 'select * from #tmp order by ' + @sortClause
EXEC(@msql)
drop table #tmp
GO

Advertencia: no he probado esto, pero "debería" funcionar en SQL Server 2005 (que creará una tabla temporal a partir de un conjunto de resultados sin especificar las columnas por adelantado).

Steven A. Lowe
fuente
2

En algún momento, ¿no vale la pena alejarse de los procedimientos almacenados y simplemente usar consultas parametrizadas para evitar este tipo de piratería?

Hank Gay
fuente
1
En ciertos casos, tal vez son mazos en un clavo, pero a menudo queremos establecer permisos (EJECUTAR en particular) directamente en los procedimientos almacenados y rechazar cualquier consulta SQL directamente en las tablas, incluso SELECT. Tampoco me gusta mucho la piratería, pero la seguridad no es mi decisión.
Sean Hanley
1
Esta es la razón por la cual tantas personas se están moviendo al Mapeo Relacional de Objetos. Recorridos de ida y vuelta innecesarios para la clasificación, enormes bloques CASE para el mismo, actualizaciones sin sentido para toneladas de columnas cuando realmente solo una necesita ser actualizada, etc. El único argumento ganador para los procedimientos almacenados que aún permanece es la seguridad.
Pittsburgh DBA
Me estoy moviendo de un ORM (EF) a un procedimiento almacenado porque el ORM no admite la búsqueda de texto completo.
Ronnie Overby
@RonnieOverby La búsqueda de texto completo a menudo está mejor servida por una solución dedicada, por ejemplo, Lucene.
Hank Gay
@HankGay Tengo la extraña sensación de que el marco de la entidad tampoco es compatible con Lucene.
Ronnie Overby
2

Estoy de acuerdo, use el lado del cliente. Pero parece que esa no es la respuesta que desea escuchar.

Entonces, es perfecto tal como es. No sé por qué querrías cambiarlo, o incluso preguntar "¿Hay una mejor manera?" Realmente, debería llamarse "The Way". Además, parece funcionar bien y se adapta bien a las necesidades del proyecto y probablemente será lo suficientemente extensible en los próximos años. Dado que sus bases de datos no están sujetas a impuestos y la clasificación es realmente muy fácil , debería permanecer así en los próximos años.

No lo sudaría.

DS
fuente
No tengo ningún problema con el lado del cliente, ya que sigo esa ruta con las aplicaciones de Windows. ¿Pero qué hay de las aplicaciones web? No encuentro mucha solución JavaScript lo suficientemente flexible. Y sí, funciona como dije de la manera en que lo tenemos, pero es una pesadilla de SQL. Por supuesto, me gustaría saber si hay mejores formas.
Sean Hanley
Está integrado en los controles .NET más nuevos (2.0 y superiores). O puede crear el suyo propio y aplicarlo a una vista de datos. msdn.microsoft.com/en-us/library/hwf94875(VS.80).aspx
DS
2
Mi problema es uno de escalabilidad y rendimiento. La ordenación del lado del cliente o del lado del servidor web requiere cargar todos los datos en lugar de solo los 10 o 15 que va a mostrar en una página a la vez. Esto es extremadamente costoso a largo plazo, mientras que la ordenación de la base de datos no tiene eso.
Sean Hanley
2

Cuando busca resultados ordenados, el SQL dinámico es una buena opción. Si eres paranoico acerca de la inyección SQL, puedes usar los números de columna en lugar del nombre de la columna. He hecho esto antes de usar valores negativos para descender. Algo como esto...

declare @o int;
set @o = -1;

declare @sql nvarchar(2000);
set @sql = N'select * from table order by ' + 
    cast(abs(@o) as varchar) + case when @o < 0 then ' desc' else ' asc' end + ';'

exec sp_executesql @sql

Entonces solo necesita asegurarse de que el número esté dentro de 1 a # de columnas. Incluso podría expandir esto a una lista de números de columna y analizarlo en una tabla de entradas usando una función como esta . Entonces construirías el orden por cláusula así ...

declare @cols varchar(100);
set @cols = '1 -2 3 6';

declare @order_by varchar(200)

select @order_by = isnull(@order_by + ', ', '') + 
        cast(abs(number) as varchar) + 
        case when number < 0 then ' desc' else '' end
from dbo.iter_intlist_to_tbl(@cols) order by listpos

print @order_by

Un inconveniente es que debe recordar el orden de cada columna en el lado del cliente. Especialmente, cuando no muestra todas las columnas o las muestra en un orden diferente. Cuando el cliente desea ordenar, asigna los nombres de las columnas al orden de las columnas y genera la lista de entradas.

dotjoe
fuente
Utilizamos sp_executesql para crear consultas de informes dinámicos. Muy efectivo. El SQL no se puede construir desde la aplicación, pero los parámetros simplemente se insertan donde es necesario y se ejecutan normalmente.
Josh Smeaton
2

Un argumento en contra de hacer la clasificación en el lado del cliente son los datos de gran volumen y la paginación. Una vez que el recuento de filas supera lo que puede mostrar fácilmente, a menudo está ordenando como parte de un salto / toma, que probablemente quiera ejecutar en SQL.

Para Entity Framework, puede usar un procedimiento almacenado para manejar su búsqueda de texto. Si encuentra el mismo problema de clasificación, la solución que he visto es utilizar un proceso almacenado para la búsqueda, devolviendo solo una clave de identificación establecida para la coincidencia. A continuación, vuelva a consultar (con el tipo) contra el db utilizando los identificadores en una lista (contiene). EF maneja esto bastante bien, incluso cuando el conjunto de ID es bastante grande. Sí, se trata de dos viajes de ida y vuelta, pero le permite mantener siempre su clasificación en la base de datos, lo que puede ser importante en algunas situaciones, y le impide escribir un montón de lógica en el procedimiento almacenado.

Paul Schirf
fuente
1

¿Qué tal manejar la ordenación en las cosas que muestran los resultados: cuadrículas, informes, etc. en lugar de en SQL?

EDITAR:

Para aclarar las cosas ya que esta respuesta fue rechazada anteriormente, explicaré un poco ...

Dijiste que sabías sobre la clasificación del lado del cliente pero que querías evitarlo. Esa es tu decisión, por supuesto.

Sin embargo, lo que quiero señalar es que al hacerlo en el lado del cliente, puede extraer los datos UNA VEZ y luego trabajar con ellos como desee, en lugar de hacer múltiples viajes de ida y vuelta al servidor cada vez El tipo se cambia.

Su SQL Server no está siendo gravado en este momento y eso es increíble. No debe ser Pero solo porque no esté sobrecargado aún no significa que se quedará así para siempre.

Si está utilizando cualquiera de los elementos más nuevos de ASP.NET para mostrar en la web, muchos de esos elementos ya están integrados.

¿Vale la pena agregar tanto código a cada procedimiento almacenado solo para manejar la clasificación? De nuevo, tu llamada.

No soy yo quien finalmente se encargará de apoyarlo. Pero piense en lo que implicará a medida que se agregan / eliminan columnas dentro de los diversos conjuntos de datos utilizados por los procedimientos almacenados (que requieren modificaciones a las declaraciones CASE) o cuando de repente, en lugar de ordenar por dos columnas, el usuario decide que necesita tres: requiriendo que actualice ahora cada uno de sus procedimientos almacenados que utiliza este método.

Para mí, vale la pena obtener una solución del lado del cliente que funcione y aplicarla a un puñado de pantallas de datos orientadas al usuario y terminar con eso. Si se agrega una nueva columna, ya está manejada. Si el usuario desea ordenar por múltiples columnas, puede ordenar por dos o veinte de ellas.

Kevin Fairchild
fuente
Esa sería la manera correcta, pero no se considera "una mejor manera"
DS
Porque aún sigo escribiendo mi propia clasificación en C # o JavaScript y parece que debería ser mucho más fácil y rápido en SQL. De ahí mi pregunta. ¿Me faltaba algo obvio o estamos atascados escribiendo nuestra propia clasificación personalizada (en C # o JavaScript) en cada maldita aplicación en la que trabajamos?
Sean Hanley
3
Espera, ¿qué pasa con los conjuntos de resultados con decenas de miles de filas? No puede devolver todos esos datos al cliente. Tiene que hacer paginación y clasificación en la base de datos.
Eric Z Beard
Yadyn, entendido. Pero una vez que tiene un clasificador genérico para sus cuadrículas, simplemente lo usa para todas sus cosas.
Kevin Fairchild
Eric, cierto ... En casos como ese, necesitas un manejo adicional y tal vez tenga sentido dentro de SQL. Está lejos de ser un problema correcto o incorrecto. En algunos casos, tendrá sentido para SQL y algunos casos, en el cliente.
Kevin Fairchild
1

Lo siento, llego tarde a la fiesta, pero aquí hay otra opción para aquellos que realmente quieren evitar el SQL dinámico, pero quieren la flexibilidad que ofrece:

En lugar de generar dinámicamente el SQL sobre la marcha, escriba código para generar un proceso único para cada variación posible. Luego puede escribir un método en el código para ver las opciones de búsqueda y hacer que elija el proceso apropiado para llamar.

Si solo tiene algunas variaciones, puede crear los procedimientos a mano. Pero si tiene muchas variaciones, en lugar de tener que mantenerlas todas, simplemente mantendrá su generador de procesos para que las vuelva a crear.

Como beneficio adicional, obtendrá mejores planes de SQL para un mejor rendimiento al hacerlo también de esta manera.

Bvernon
fuente
-1

Es posible que esta solución solo funcione en .NET, no lo sé.

Busco los datos en C # con el orden de clasificación inicial en el orden de SQL por cláusula, pongo esos datos en un DataView, los almacena en caché en una variable de sesión y los uso para construir una página.

Cuando el usuario hace clic en el encabezado de una columna para ordenar (o página, o filtro), no vuelvo a la base de datos. En cambio, vuelvo a mi DataView en caché y establezco su propiedad "Ordenar" en una expresión que construyo dinámicamente, al igual que lo haría con SQL dinámico. (Realizo el filtrado de la misma manera, usando la propiedad "RowFilter").

Puede verlo / sentirlo funcionando en una demostración de mi aplicación, BugTracker.NET, en http://ifdefined.com/btnet/bugs.aspx

Corey Trager
fuente
¡DULCE! Bug tracker.NET rocks!
digiguru
-7

Debe evitar la ordenación de SQL Server, a menos que sea necesario. ¿Por qué no ordenar en el servidor de aplicaciones o en el lado del cliente? También .NET Generics hace una clasificación excepcional

Saif Khan
fuente
66
Debido a la escalabilidad. Está bien para unos pocos miles de filas, pero no quiero tirar de diez mil y ordenar eso. O más. Además, ¿qué pasa con la paginación? A menudo solo quiero obtener lo que necesito mostrar. Ordenar las filas 21-30 de 24056 después del hecho sería incorrecto.
Sean Hanley