Ordinamento dinamico in SQL Stored Procedures


126

Questo è un problema che ho passato ore a ricercare in passato. Mi sembra essere qualcosa che avrebbe dovuto essere affrontato dai moderni RDBMS soluzioni , ma finora non ho trovato nulla che risolva realmente ciò che vedo essere un'esigenza incredibilmente comune in qualsiasi applicazione Web o Windows con un back-end di database.

Parlo di ordinamento dinamico. Nel mio mondo fantasy, dovrebbe essere semplice come qualcosa come:

ORDER BY @sortCol1, @sortCol2

Questo è l'esempio canonico fornito dagli sviluppatori principianti di SQL e Stored Procedure in tutti i forum su Internet. "Perché non è possibile?" loro chiedono. Invariabilmente, qualcuno alla fine arriva per tenere lezioni sulla natura compilata delle procedure archiviate, dei piani di esecuzione in generale e di ogni sorta di altri motivi per cui non è possibile inserire un parametro direttamente in una ORDER BYclausola.


So cosa stanno già pensando alcuni di voi: "Lasciate che il cliente faccia l'ordinamento, allora." Naturalmente, questo scarica il lavoro dal tuo database. Nel nostro caso, tuttavia, i nostri server di database non hanno nemmeno sudato il 99% delle volte e non sono nemmeno multi-core o nessuna delle altre miriadi di miglioramenti all'architettura di sistema che si verificano ogni 6 mesi. Solo per questo motivo, avere i nostri database in grado di gestire l'ordinamento non sarebbe un problema. Inoltre, i database sono moltobravo nell'ordinamento. Sono ottimizzati per questo e hanno avuto anni per farlo bene, il linguaggio per farlo è incredibilmente flessibile, intuitivo e semplice e soprattutto qualsiasi scrittore SQL principiante sa come farlo e ancora più importante sa come modificarlo, apportare modifiche, eseguire interventi di manutenzione, ecc. Quando i database non sono tassati e si desidera solo semplificare (e abbreviare!) i tempi di sviluppo, questa sembra una scelta ovvia.

Quindi c'è il problema web. Ho giocato con JavaScript che eseguirà l'ordinamento sul lato client di tabelle HTML, ma inevitabilmente non sono abbastanza flessibili per le mie esigenze e, ancora una volta, poiché i miei database non sono eccessivamente tassati e possono fare l'ordinamento molto facilmente, io fare fatica a giustificare il tempo necessario per riscrivere o eseguire il rullaggio del mio selezionatore JavaScript. Lo stesso vale in genere per l'ordinamento sul lato server, anche se probabilmente è già molto preferito su JavaScript. Non sono uno a cui piace particolarmente il sovraccarico di DataSet, quindi fammi causa.

Ma questo riporta il punto che non è possibile - o meglio, non facilmente. Ho fatto, con i sistemi precedenti, un modo incredibilmente hack per ottenere l'ordinamento dinamico. Non era carino, né intuitivo, semplice o flessibile e uno scrittore SQL per principianti si sarebbe perso in pochi secondi. Già questo non sembra essere tanto una "soluzione" ma una "complicazione".


I seguenti esempi non intendono esporre alcun tipo di best practice o buon stile di codifica o altro, né sono indicativi delle mie capacità di programmatore T-SQL. Sono quello che sono e ammetto pienamente che sono confusi, cattivi in ​​forma e semplicemente hack.

Passiamo un valore intero come parametro a una procedura memorizzata (chiamiamo il parametro solo "ordina") e da ciò determiniamo un gruppo di altre variabili. Ad esempio ... diciamo che l'ordinamento è 1 (o il valore predefinito):

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

Puoi già vedere come se dichiarassi più variabili @colX per definire altre colonne, potrei davvero essere creativo con le colonne su cui ordinare in base al valore di "sort" ... per usarlo, di solito finisce come il seguente clausola incredibilmente disordinata:

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

Ovviamente questo è un esempio molto ridotto. Il vero materiale, dal momento che di solito abbiamo quattro o cinque colonne per supportare l'ordinamento, ognuna con possibili secondarie o anche una terza colonna su cui ordinare oltre a quella (ad esempio data decrescente quindi ordinata secondariamente per nome crescente) e ogni bi-supporto ordinamento direzionale che raddoppia efficacemente il numero di casi. Sì ... diventa peloso molto velocemente.

L'idea è che si potrebbe "facilmente" cambiare i casi di ordinamento in modo tale che il veicoloid venga ordinato prima del tempo memorizzato ... ma la pseudo-flessibilità, almeno in questo semplice esempio, finisce davvero lì. In sostanza, ogni caso che fallisce un test (perché il nostro metodo di ordinamento non si applica ad esso questa volta) rende un valore NULL. E così finisci con una clausola che funziona come la seguente:

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

Ti viene l'idea. Funziona perché SQL Server ignora efficacemente i valori null in ordine di clausole. Questo è incredibilmente difficile da mantenere, come probabilmente può vedere chiunque abbia una conoscenza base di SQL. Se ho perso qualcuno di voi, non stare male. Ci è voluto molto tempo per farlo funzionare e ci confondiamo ancora cercando di modificarlo o crearne di nuovi simili. Per fortuna non ha bisogno di cambiare spesso, altrimenti diventerebbe rapidamente "non vale la pena".

Eppure ha fatto il lavoro.


La mia domanda è quindi: esiste un modo migliore?

Sto bene con soluzioni diverse da quelle memorizzate, poiché mi rendo conto che potrebbe non essere la strada da percorrere. Preferibilmente, vorrei sapere se qualcuno può farlo meglio all'interno della Stored Procedure, ma in caso contrario, come gestite tutti voi consentendo all'utente di ordinare dinamicamente tabelle di dati (anche bidirezionali) con ASP.NET?

E grazie per aver letto (o almeno scremato) una domanda così lunga!

PS: Sii contento di non aver mostrato il mio esempio di una procedura memorizzata che supporta l'ordinamento dinamico, il filtro dinamico / la ricerca di testo delle colonne, l'impaginazione tramite ROWNUMBER () OVER, E prova ... a intercettare il rollback delle transazioni sugli errori ... "behemoth-size" non inizia nemmeno a descriverli.


Aggiornare:

  • Vorrei evitare SQL dinamico . L'analisi di una stringa insieme e l'esecuzione di un EXEC su di essa vanifica molto lo scopo di avere una procedura memorizzata in primo luogo. A volte mi chiedo se i contro del fare una cosa del genere non varrebbero la pena, almeno in questi casi di smistamento dinamico speciali. Tuttavia, mi sento sempre sporco ogni volta che eseguo stringhe SQL dinamiche del genere, come se vivessi ancora nel mondo ASP classico.
  • Molte delle ragioni per cui vogliamo che le procedure archiviate siano innanzitutto legate alla sicurezza . Non riesco a fare la chiamata per motivi di sicurezza, suggerisco solo soluzioni. Con SQL Server 2005 possiamo impostare le autorizzazioni (su base per utente se necessario) a livello di schema su singole procedure memorizzate e quindi negare direttamente qualsiasi query sulle tabelle. Criticare i pro ei contro di questo approccio è forse per un'altra domanda, ma ancora una volta non è una mia decisione. Sono solo la scimmia del codice principale. :)

Consultare anche stackoverflow.com/questions/3659981/… - SQL Server dinamico ORDER BY con tipi di dati misti
LCJ

SQL dinamico è il modo FAR superiore ... IF [e questo è un grande IF] .. il tuo livello di accesso ai dati è rigoroso e il tuo SQL dinamico è generato da un sistema che è rigidamente programmato con regole RDBMS espresse in forma perfetta. Un'architettura di database ingegnerizzata algoritmicamente è una cosa di bellezza ...
hajikelist

Risposte:


97

Sì, è un dolore, e il modo in cui lo fai è simile a quello che faccio:

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

Questo, per me, è ancora molto meglio della creazione di SQL dinamico dal codice, che si trasforma in un incubo di scalabilità e manutenzione per i DBA.

Quello che faccio dal codice è il refactoring del paging e dell'ordinamento, quindi almeno non ho molta ripetizione lì con i valori di popolamento per @SortExpre @SortDir.

Per quanto riguarda l'SQL, mantieni la progettazione e la formattazione uguali tra le diverse procedure memorizzate, quindi è almeno pulito e riconoscibile quando entri per apportare modifiche.


1
Esattamente. Il mio obiettivo era quello di evitare di eseguire un comando EXEC su una grande stringa varchar da 5000. Tutto ciò che facciamo deve essere eseguito tramite procedure memorizzate, se non altro per la sicurezza aggiuntiva, poiché possiamo impostare autorizzazioni su di esse a livello di schema. La scalabilità e le prestazioni sono solo un vantaggio nel nostro caso.
Sean Hanley,

1
Aggiungi manutenibilità a {sicurezza, scalabilità, prestazioni}. Una volta che hai 3 o 4 app là fuori con SQL dinamico in esecuzione sul tuo DB, sei fregato, non puoi cambiare nulla, specialmente con il passare degli anni e degli sviluppatori che passano. Exec e sql dinamico sono malvagi.
Eric Z Beard,

È proprio così --- lo facciamo già, molto prima che arrivassi qui, per tutte le app Web ASP classiche ancora in esecuzione e molte, molte app Access VB ancora in circolazione. Contraggo e devo trattenere gli impulsi per correggere errori evidenti ogni volta che devo eseguire la manutenzione su uno di essi.
Sean Hanley,

1
Questo è ciò che faccio anche, tranne che per codificare la direzione in SortExpr: ORDINA PER CASO QUANDO sort = 'FirstName' THEN FirstName END ASC, CASE WHEN sort = '-FirstName' THEN FirstName END DESC
Michael Bray

Questo è L'incubo per DBA e ingegneri del software. Quindi, invece di essere in grado di avere sistemi dinamici ma rigorosi che generano istruzioni SQL espressive basate sul tuo schema di informazioni, hai questo disgustoso glop di incomprensibile codificazione. È una programmazione scadente al massimo.
hajikelist

23

Questo approccio impedisce alle colonne ordinabili di essere duplicate due volte nell'ordine, ed è un po 'più leggibile IMO:

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

Sembrava una buona risposta, ma non sembra funzionare quando le colonne ordinabili hanno tipi di dati diversi
SlimSim


6

Le mie applicazioni lo fanno molto, ma stanno tutti costruendo in modo dinamico l'SQL. Tuttavia, quando ho a che fare con le stored procedure, lo faccio:

  1. Rendi la procedura memorizzata una funzione che restituisce una tabella dei tuoi valori - nessun ordinamento.
  2. Quindi, nel codice dell'applicazione, esegui una operazione in select * from dbo.fn_myData() where ... order by ...modo da poter specificare in modo dinamico l'ordinamento lì.

Quindi almeno la parte dinamica è nella tua applicazione, ma il database sta ancora eseguendo il lavoro pesante.


1
Questo è probabilmente il miglior compromesso che abbia mai visto tra l'utilizzo di SQL dinamico e le procedure memorizzate insieme. Mi piace. Potrei sperimentare qualche volta con un approccio simile, ma un simile cambiamento sarebbe proibitivo in uno qualsiasi dei nostri progetti in corso.
Sean Hanley,

1
È possibile ottenere lo stesso risultato utilizzando una variabile di tabella locale anziché la funzione tabulare che restituisce i dati. Trovo che le tabelle locali siano più flessibili delle funzioni, in quanto è possibile generare alcune informazioni di debug.
Sanjay Zalke,

5

Una tecnica di procedura memorizzata (hack?) Che ho usato per evitare l'SQL dinamico per alcuni lavori è avere una colonna di ordinamento univoca. Vale a dire,

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

Questo è facile da superare nell'invio: puoi concatenare i campi nella colonna mySort, invertire l'ordine con le funzioni matematiche o di data, ecc.

Preferibilmente, però, utilizzo la mia griglia di asp.net o altri oggetti con ordinamento incorporato per eseguire l'ordinamento DOPO il recupero dei dati da SQL Server. O anche se non è integrato - ad es., Banche dati, ecc. In asp.net.


4

Ci sono un paio di modi diversi in cui puoi hackerarlo.

Prerequisiti:

  1. Solo un'istruzione SELECT nello sp
  2. Escludere qualsiasi ordinamento (o avere un valore predefinito)

Quindi inserire in una tabella temporanea:

create table #temp ( your columns )

insert #temp
exec foobar

select * from #temp order by whatever

Metodo n. 2: impostare nuovamente un server collegato su se stesso, quindi selezionare da questo usando openquery: http://www.sommarskog.se/share_data.html#OPENQUERY


4

Potrebbe esserci una terza opzione, poiché il tuo server ha molti cicli di riserva: usa una procedura di supporto per eseguire l'ordinamento tramite una tabella temporanea. Qualcosa di simile a

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

Avvertenza: non l'ho testato, ma "dovrebbe" funzionare in SQL Server 2005 (che creerà una tabella temporanea da un set di risultati senza specificare in anticipo le colonne).


2

Ad un certo punto, non vale la pena allontanarsi dalle procedure memorizzate e utilizzare solo query con parametri per evitare questo tipo di hacking?


1
In alcuni casi forse sono mazze su un chiodo, ma spesso vogliamo impostare le autorizzazioni (in particolare EXECUTE) direttamente sulle procedure memorizzate e non consentire qualsiasi query SQL direttamente contro le tabelle, anche con SELECT. Neanche a me piace molto l'hacking, ma la sicurezza non è la mia chiamata da fare.
Sean Hanley,

1
Questo è il motivo per cui così tante persone stanno passando alla mappatura relazionale degli oggetti. Inutili viaggi di andata e ritorno per l'ordinamento, enormi blocchi CASE per gli stessi, insensati aggiornamenti a tonnellate di colonne quando in realtà è necessario aggiornarne solo una, ecc. L'argomento vincente per le procedure memorizzate che rimane ancora è la sicurezza.
Pittsburgh DBA,

Sto passando da un ORM (EF) a una procedura memorizzata perché l'ORM non supporta la ricerca full-text.
Ronnie Overby,

@RonnieOverby La ricerca full-text è spesso servita meglio da una soluzione dedicata, ad esempio Lucene.
Hank Gay,

@HankGay Ho la strana sensazione che anche il framework di entità non supporti Lucene.
Ronnie Overby,

2

Sono d'accordo, utilizzare il lato client. Ma sembra che non sia la risposta che vuoi sentire.

Quindi, è perfetto così com'è. Non so perché vorresti cambiarlo, o anche chiedere "C'è un modo migliore". Davvero, dovrebbe essere chiamato "The Way". Inoltre, sembra funzionare e soddisfare bene le esigenze del progetto e probabilmente sarà abbastanza estensibile per gli anni a venire. Poiché i tuoi database non sono tassati e l'ordinamento è davvero molto semplice , dovrebbe rimanere tale per gli anni a venire.

Non vorrei sudare.


Non ho alcun problema con il lato client, mentre percorro questa strada con le app di Windows. E le app Web? Non trovo molto flessibile alcuna soluzione JavaScript abbastanza flessibile. E sì, funziona come ho detto come lo abbiamo noi, ma è un incubo di SQL. Certo, vorrei sapere se ci sono modi migliori.
Sean Hanley,

È integrato nei controlli .NET più recenti (2.0 e successivi). Oppure puoi crearne uno tuo e applicarlo a una visualizzazione dati. msdn.microsoft.com/en-us/library/hwf94875(VS.80).aspx
DS

2
Il mio problema è quindi di scalabilità e prestazioni. L'ordinamento lato client o lato server richiede il caricamento di tutti i dati anziché solo i 10 o 15 che verranno visualizzati su una pagina alla volta. Questo è estremamente costoso, a lungo termine, mentre l'ordinamento del database non lo possiede.
Sean Hanley,

2

Quando si esegue il paging dei risultati ordinati, SQL dinamico è una buona opzione. Se sei paranoico sull'iniezione SQL, puoi utilizzare i numeri di colonna anziché il nome della colonna. L'ho fatto prima di usare valori negativi per la discesa. Qualcosa come questo...

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

Quindi devi solo assicurarti che il numero sia compreso tra 1 e # delle colonne. Puoi persino espandere questo in un elenco di numeri di colonna e analizzarlo in una tabella di ints usando una funzione come questa . Quindi costruiresti l'ordine in base alla clausola in questo modo ...

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

Uno svantaggio è che devi ricordare l'ordine di ogni colonna sul lato client. Soprattutto, quando non visualizzi tutte le colonne o le visualizzi in un ordine diverso. Quando il client desidera ordinare, associare i nomi delle colonne all'ordine delle colonne e generare l'elenco di ints.


Usiamo sp_executesql per creare query di report dinamici. Molto efficace. L'SQL non può essere creato dall'applicazione, ma i parametri vengono semplicemente inseriti dove necessario ed eseguiti normalmente.
Josh Smeaton,

2

Un argomento contro fare l'ordinamento sul lato client sono i grandi volumi di dati e l'impaginazione. Una volta che il conteggio delle righe supera quello che è possibile visualizzare facilmente, spesso si esegue l'ordinamento come parte di un salto / take, che probabilmente si desidera eseguire in SQL.

Per Entity Framework, è possibile utilizzare una procedura memorizzata per gestire la ricerca di testo. Se si riscontra lo stesso problema di ordinamento, la soluzione che ho visto è utilizzare un proc memorizzato per la ricerca, restituendo solo una chiave id impostata per la corrispondenza. Quindi, eseguire nuovamente la query (con l'ordinamento) sul db utilizzando gli ID in un elenco (contiene). EF lo gestisce abbastanza bene, anche quando l'ID set è piuttosto grande. Sì, si tratta di due round trip, ma ti consente di mantenere sempre il tuo ordinamento nel DB, che può essere importante in alcune situazioni, e ti impedisce di scrivere un carico di logica nella procedura memorizzata.


1

Che ne dici di gestire l'ordinamento delle cose che mostrano i risultati - griglie, report, ecc. Piuttosto che su SQL?

MODIFICARE:

Per chiarire le cose dal momento che questa risposta è stata sotto-votata in precedenza, elaborerò un po '...

Hai dichiarato di conoscere l'ordinamento sul lato client, ma volevi evitare. Questa è la tua chiamata, ovviamente.

Quello che voglio sottolineare, tuttavia, è che facendolo sul lato client, sei in grado di estrarre i dati UNA VOLTA e quindi lavorare con esso come preferisci, anziché fare più viaggi avanti e indietro sul server ogni volta l'ordinamento viene modificato.

Il tuo SQL Server non viene tassato in questo momento ed è fantastico. Non dovrebbe essere. Ma solo perché non è ancora sovraccarico non significa che rimarrà così per sempre.

Se stai utilizzando una delle cose ASP.NET più recenti per la visualizzazione sul Web, molte di queste cose sono già inserite.

Vale la pena aggiungere così tanto codice a ogni procedura memorizzata solo per gestire l'ordinamento? Ancora una volta, la tua chiamata.

Non sono io quello che alla fine sarà incaricato di sostenerlo. Ma pensa a cosa sarà coinvolto quando le colonne vengono aggiunte / rimosse all'interno dei vari set di dati utilizzati dalle procedure memorizzate (che richiedono modifiche alle istruzioni CASE) o quando improvvisamente invece di ordinare per due colonne, l'utente decide di averne bisogno di tre: richiedendo di aggiornare ora ciascuna delle procedure memorizzate che utilizza questo metodo.

Per me, ne vale la pena ottenere una soluzione lato client funzionante e applicarla a una manciata di visualizzazioni dei dati rivolte all'utente e farla finita. Se viene aggiunta una nuova colonna, è già gestita. Se l'utente desidera ordinare in base a più colonne, può ordinarne due o venti.


Sarebbe il modo giusto, ma non è considerato "un modo migliore"
DS

Perché poi sto ancora scrivendo il mio ordinamento in C # o JavaScript e sembra che dovrebbe essere molto più semplice e veloce in SQL. Quindi la mia domanda. Mi mancava qualcosa di ovvio o siamo bloccati a scrivere il nostro ordinamento personalizzato (in C # o JavaScript) su ogni dannata app su cui lavoriamo?
Sean Hanley,

3
Aspetta, che dire dei set di risultati con decine di migliaia di righe? Non è possibile restituire tutti quei dati al client. È necessario eseguire il paging e l'ordinamento nel database.
Eric Z Beard,

Yadyn, capito. Ma una volta che hai un selezionatore generico per le tue griglie, lo usi solo per tutte le tue cose.
Kevin Fairchild,

Eric, True ... In casi del genere, hai bisogno di una gestione extra e forse avrebbe senso in SQL. È tutt'altro che un problema giusto o sbagliato. In alcuni casi, avrà senso per SQL e alcuni casi, sul client.
Kevin Fairchild,

1

Mi dispiace, sono in ritardo alla festa, ma ecco un'altra opzione per coloro che vogliono davvero evitare l'SQL dinamico, ma vogliono la flessibilità che offre:

Invece di generare dinamicamente SQL al volo, scrivere il codice per generare un proc unico per ogni possibile variazione. Quindi è possibile scrivere un metodo nel codice per esaminare le opzioni di ricerca e fare in modo che scelga il proc appropriato da chiamare.

Se hai solo alcune varianti, puoi semplicemente creare i proc a mano. Ma se hai molte varianti, invece di doverle mantenere tutte, manterrai semplicemente il tuo generatore di proc invece che le ricreasse.

Come ulteriore vantaggio, otterrai piani SQL migliori per prestazioni migliori anche in questo modo.


-1

Questa soluzione potrebbe funzionare solo in .NET, non lo so.

Recupero i dati in C # con il criterio di ordinamento iniziale nella clausola order by SQL, li inserisco in un DataView, li inserisco nella cache di una variabile Session e li utilizzo per creare una pagina.

Quando l'utente fa clic sull'intestazione di una colonna per ordinare (o pagina o filtro), non torno al database. Invece, torno al mio DataView memorizzato nella cache e imposto la sua proprietà "Ordina" su un'espressione che creo dinamicamente, proprio come farei SQL dinamico. (Faccio il filtro allo stesso modo, usando la proprietà "RowFilter").

Puoi vederlo / sentirlo funzionare in una demo della mia app, BugTracker.NET, all'indirizzo http://ifdefined.com/btnet/bugs.aspx


DOLCE! Bug tracker.NET rock!
digiguru,

-7

È necessario evitare l'ordinamento di SQL Server, a meno che non sia necessario. Perché non ordinare sul server delle applicazioni o sul lato client? Anche .NET Generics esegue un ordinamento eccezionale


6
A causa della scalabilità. Va bene per qualche migliaio di file, ma non voglio abbatterne diecimila e sistemarlo. O più. Inoltre, per quanto riguarda il paging? Spesso voglio solo inserire ciò che devo visualizzare. L'ordinamento delle righe 21-30 di 24056 dopo il fatto sarebbe errato.
Sean Hanley,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.