BETWEEN su anno

venerdì 06 novembre 2009 - 10.31

Blacky Profilo | Newbie

Ciao, ho una tabellina contenente fatture cosi formata: ID | IMPORTO | DATA

La data è in formato datetime standard quindi ad esempio: 2009-01-29 00:00:00.000

In una pagina ASPNET ho una dropdownlist che espone 4 campi: 2008 - 2009 - 2010 - 2011.

Quando si seleziona uno dei campi relativi agli anni, viene passato un parametro (@anno) alla mia query.

Il problema è che non so come farla...
Dovrebbe essere un qualcosa del tipo:
SELECT * from FAT where anno between @anno+'-01-01' AND @anno+'-12-31'

Ma ovviamente non funziona...

C'è una soluzione?

Grazie, Francy

speedx Profilo | Junior Member

Per farla come vuoi tu devi prima scrivere tutta la query come stringa e metterla in una variabile di tipo testo:

@VARSQL = 'SELECT * FROM FAT WHERE Data ' + @Anno+ '-01-01' ecc...

E poi fare

EXECUTE(@VARSQL)

in alternativa puoi mettere la codifica data durante la selezione dall'interfaccia.... mettendo un po di codice li



//// Marcello C.

lbenaglia Profilo | Guru

>Ciao, ho una tabellina contenente fatture cosi formata: ID |
>IMPORTO | DATA
>
>La data è in formato datetime standard quindi ad esempio: 2009-01-29
>00:00:00.000
>
>In una pagina ASPNET ho una dropdownlist che espone 4 campi:
>2008 - 2009 - 2010 - 2011.
>
>Quando si seleziona uno dei campi relativi agli anni, viene passato
>un parametro (@anno) alla mia query.
>
>Il problema è che non so come farla...
>Dovrebbe essere un qualcosa del tipo:
>SELECT * from FAT where anno between @anno+'-01-01' AND @anno+'-12-31'
>
>Ma ovviamente non funziona...
>
>C'è una soluzione?

Ciao Francy,

Supponendo che @anno sia int e che nella WHERE hai specificato erroneamente la colonna "anno" (che non esiste), puoi castare il parametro a char prima di concatenarlo al mese/giorno:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

>Grazie, Francy
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

lbenaglia Profilo | Guru

>Per farla come vuoi tu devi prima scrivere tutta la query come
>stringa e metterla in una variabile di tipo testo:
>
>@VARSQL = 'SELECT * FROM FAT WHERE Data ' + @Anno+ '-01-01' ecc...
>
>E poi fare
>
>EXECUTE(@VARSQL)
Occhio al Dynamic SQL ed ai relativi problemi che può generare (primo tra tutti attacchi di SQL Injection...)

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

Blacky Profilo | Newbie

Grazie ad entrambi miei gladiatori SQL! :-P

RoBYCoNTe Profilo | Newbie

scusate... ma la soluzione più semplice non è....
WHERE YEAR(DATA) = @Anno

lbenaglia Profilo | Guru

>scusate... ma la soluzione più semplice non è....
>
>WHERE YEAR(DATA) = @Anno

Ciao Roberto,

Si, è decisamente semplice ma estremamente lenta dato che la funzione YEAR() verrà applicata alla colonna Data per tutte le righe della tabella.
Inoltre eventuali indici definiti sulla colonna Data saranno ignorati eseguendo sempre un table scan.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

RoBYCoNTe Profilo | Newbie

Lenta? Penso sia un pò difficile pensare che questa funzione sia lenta e penso sia ancora più difficile trovare "Indici" su un campo di tipo datetime, lavoro su sistemi in cui l'utenza e la mole di dati da gestire si basano su un ordine di grandezza dei milioni (aziende sanitarie), mi è già capitato di utilizzare filtri di questo tipo senza notare alcun calo di prestazioni. Premetto che progetto una query sempre tenendo conto dell'analisi in termini di costo di questa all'interno del db ed è proprio l'analisi prestazionale che indica i costi di una funzione parti a 0.

Vorrei anche ricordare che le funzioni sql server sono native c, ciò dovrebbe già mostrare la loro efficacia e velocità di utilizzo.



Senza contare il fatto che sono d'accordo con te quando parli di sql injection :) un sistema di grandi dimensioni utilizzerebbe stored procedure, l'utente in questione non penso abbiamo necessita di gestire triliardi di dati.

lbenaglia Profilo | Guru

>Lenta? Penso sia un pò difficile pensare che questa funzione
>sia lenta e penso sia ancora più difficile trovare "Indici" su
>un campo di tipo datetime
Applicala ad una tabella con qualche milione di righe e poi ne riparliamo, soprattutto quando esistono soluzioni alternative più efficienti (come quella proposta).
Indici su datetime? Oh mamma, se si eseguono query su intervalli di date, un bel clustered non ce lo leva nessuno!

>lavoro su sistemi in cui l'utenza
>e la mole di dati da gestire si basano su un ordine di grandezza
>dei milioni (aziende sanitarie), mi è già capitato di utilizzare
>filtri di questo tipo senza notare alcun calo di prestazioni.
Confronta tempi e piani di esecuzione...

>Premetto che progetto una query sempre tenendo conto dell'analisi
>in termini di costo di questa all'interno del db ed è proprio
>l'analisi prestazionale che indica i costi di una funzione parti
>a 0.
>
>Vorrei anche ricordare che le funzioni sql server sono native
>c, ciò dovrebbe già mostrare la loro efficacia e velocità di
>utilizzo.
Non è questione di efficienza del codice della funzione, quanto di piano di esecuzione.
Concordi che applicare una funzione a TUTTE le righe di una tabella sia meno efficiente rispetto a NON applicarla ad un range (magari ordinato fisicamente grazie ad un indice clustered)?

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

RoBYCoNTe Profilo | Newbie

Su questo concordo! :D
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5