SELECT MIN()

domenica 09 marzo 2008 - 12.16

albedo Profilo | Junior Member

Ciao, Ragazzi

Vorrei riportare il valore minimo di una serie di record in una text box, ho provato in questo modo, ma mi restituisce un errore:

cmd = New OleDb.OleDbCommand("SELECT MIN(ESISTENZA) FROM GIACENZE WHERE FORNITORE = 'XXX'", cn)
Dr = cmd.ExecuteReader

f dr.HasRows Then
While dr.Read
Form1.TextBox2.Text = dr.Item("ESISTENZA")
End While
Else
Form1.TextBox2.Text = 0
End If

Grazie

StefanoLep Profilo | Senior Member

Ciao, sostituisci .item("Esistenza") con .Item(0)
Immagino che l'errore sia che non trova il campo...:-)
E' la passione che genera il progresso :-)

albedo Profilo | Junior Member

No, è la stessa cosa.

Grazie comunque

alx_81 Profilo | Guru

Ciao!
Quale sarebbe l'errore che ottieni?
A me sembra che non apri la connessiome, e se non lo fai, non c'è possibilità di leggere i dati .
Poi devi mettere l'alias nella query, per dare il nome Esistenza al campo:

SELECT MIN(Esistenza) AS Esistenza FROM Giacenze WHERE Fornitore = 'xxx'

Fai queste cose e tutto dovrebbe funzionare

Tuttavia mi permetto di dirti di attivare l'option strict, perchè sembra che non sia attivo.
Fai attenzione perchè un controllo sulla tipizzazione (rendendola "forte" on l'opzione attivata) ti consente di avere codice migliore e affidabile.

Ciao!

Alx81 =)

http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

albedo Profilo | Junior Member

>Ciao!
>Quale sarebbe l'errore che ottieni?
>
>Alx81 =)
>
>http://blogs.dotnethell.it/suxstellino
>http://mvp.support.microsoft.com/profile/Alessandro.Alpi
>http://italy.mvps.org

System.IndexOutOfRangeException

Nella tabella è presente una sola riga...

La sintassi della query credo sia corretta, è il datareader che dà probòemi.

Ciao

alx_81 Profilo | Guru

>La sintassi della query credo sia corretta, è il datareader che
>dà probòemi.
Hai messo l'alias?

a parte il fatto che se devi tornare un solo campo, usa la ExecuteScalar..

Alx81 =)

http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

lbenaglia Profilo | Guru

>System.IndexOutOfRangeException
Quale riga di codice scatena questa eccezione?
Nel tuo esempio dr.Item("ESISTENZA") non può funzionare dato che la SELECT non ha alcun alias di colonna applicato alla funzione di aggregazione MIN(), però dr.Item(0) dovrebbe funzionare (come suggerisce Stefano).

>La sintassi della query credo sia corretta, è il datareader che
>dà probòemi.
La query sintatticamente è corretta, bisogna vedere su che struttura si basa.
Che DBMS utilizzi? Con SQL Server potresti provarla ad esempio con il Query Analyzer (SQL Server 2000) oppure SQL Server Management Studio (SQL Server 2005).

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

albedo Profilo | Junior Member

>>La sintassi della query credo sia corretta, è il datareader che
>>dà probòemi.
>Hai messo l'alias?
>
>a parte il fatto che se devi tornare un solo campo, usa la ExecuteScalar..
>
>Alx81 =)
>
>http://blogs.dotnethell.it/suxstellino
>http://mvp.support.microsoft.com/profile/Alessandro.Alpi
>http://italy.mvps.org

cmd = New OleDb.OleDbCommand("SELECT MIN(ESISTENZA) AS RST FROM GIACENZE WHERE FORNITORE = '" & Item(2, rw).Value & "' AND ARTICOLO = '" & Item(4, rw).Value & "'", cn)

Ma poi come gestisco l'alias con il reader?

Cioè, come faccio a visualizzare il risultato ottenuto nelle textbox?

Ciao

lbenaglia Profilo | Guru

>cmd = New OleDb.OleDbCommand("SELECT MIN(ESISTENZA) AS RST FROM
>GIACENZE WHERE FORNITORE = '" & Item(2, rw).Value & "' AND ARTICOLO
>= '" & Item(4, rw).Value & "'", cn)
Non è che la System.IndexOutOfRangeException sia causata da quell'Item non meglio specificato?

>Cioè, come faccio a visualizzare il risultato ottenuto nelle
>textbox?
La risposta completa di esempi la trovi su MSDN:
http://msdn2.microsoft.com/it-it/library/system.data.sqlclient.sqlcommand.executescalar.aspx

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

alx_81 Profilo | Guru

>Ma poi come gestisco l'alias con il reader?
>Cioè, come faccio a visualizzare il risultato ottenuto nelle
>textbox?
Come ti torno a ripetere in questo contesto è meglio l'ExecuteScalar, che ti torna lo scalare risultante dalla tua query. Osserva il seguente esempio:
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
Fai attenzione anche a quell'array Item, non vorrei che l'errore fosse lì come ti indica Lorenzo..
Alx81 =)

http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

albedo Profilo | Junior Member

>>Ma poi come gestisco l'alias con il reader?
>>Cioè, come faccio a visualizzare il risultato ottenuto nelle
>>textbox?
>Come ti torno a ripetere in questo contesto è meglio l'ExecuteScalar,
>che ti torna lo scalare risultante dalla tua query. Osserva il
>seguente esempio:
>
>' istanzio la connessione
>Using cn As New OleDb.OleDbConnection("Provider=sqloledb;data
>source=tuoserver;initial catalog=tuodb;integrated security=SSPI;")
>' usa la tua connectionstring
>
> ' istanzio il comando con una query parametrica
>Using cmd As New OleDb.OleDbCommand("SELECT MIN(Esistenza) AS
>RST FROM Giacenze WHERE Fornitore = ? AND ARTICOLO >= ?",
>cn)
>
> ' seleziona tu i parametri corretti
>cmd.Parameters.Add("@Fornitore", OleDb.OleDbType.VarChar, 10).Value
>= "xxx" 'Item(2, rw).Value
>cmd.Parameters.Add("@Articolo", OleDb.OleDbType.Integer).Value
>= 10 'Item(4, rw).Value
>
> cn.Open()
>form1.TextBox2.Text = cmd.ExecuteScalar().ToString()
> cn.Close()
>
> End Using
>
> End Using
>
>Fai attenzione anche a quell'array Item, non vorrei che l'errore
>fosse lì come ti indica Lorenzo..
>Alx81 =)
>
>http://blogs.dotnethell.it/suxstellino
>http://mvp.support.microsoft.com/profile/Alessandro.Alpi
>http://italy.mvps.org

Confesso che mi sto perdendo...
Riesco a riempire una datagridview con qualsiasi funzione di aggrgazione (SUM, ad esempio), ma non riesco a visualizzare il valore minimo di una colonna in una textbox.
Grazie alex, ti garantisco che quell'item non rappresenta alcun problema (l'errore si manifesta asnche se scrivo la query in questo modo:cmd = New OleDb.OleDbCommand("SELECT MIN(ESISTENZA) AS RST FROM GIACENZE WHERE FORNITORE = 'MATTEO'", cn)), e preferirei usare executereader.

Ciao

alx_81 Profilo | Guru

>Confesso che mi sto perdendo...
>Grazie alex, ti garantisco che quell'item non rappresenta alcun
>problema (l'errore si manifesta asnche se scrivo la query in
>questo modo:cmd = New OleDb.OleDbCommand("SELECT MIN(ESISTENZA)
>AS RST FROM GIACENZE WHERE FORNITORE = 'MATTEO'", cn)), e preferirei
>usare executereader.
ExecuteScalar ti è stato consigliato, perchè è la cosa migliore da utilizzare in questo contesto. Se tu vuoi continuare ad utilizzare ExecuteReader, nessun problema. A prescindere da questo cerca di utilizzare le query parametriche e non la concatenazione di stringhe, in modo da bloccare i tentativi di SQL Injection.
E cerca di utilizzare la Using, per la migliore gestione delle risorse utilizzate nel tuo codice.

Tornando al tuo problema, se vuoi un aiuto, dovresti dirci qual è la riga che ti dà l'errore. Perchè se cambiando la query l'errore lo continui ad avere è probabile che non ci si debba soffermare su quella, non trovi? La query è corretta, ed videntemente quell'IndexOutOfRange è relativo a qualcosa di altro, come ad esempio Item. Matrice di cui non sappiamo nulla. Se vuoi un aiuto fai un bel debug e facci sapere su quale riga hai l'errore. ok?

Ciao!
Alx81 =)

http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

albedo Profilo | Junior Member

...
>Tornando al tuo problema, se vuoi un aiuto, dovresti dirci qual
>è la riga che ti dà l'errore. Perchè se cambiando la query l'errore
>lo continui ad avere è probabile che non ci si debba soffermare
>su quella, non trovi? La query è corretta, ed videntemente
>quell'IndexOutOfRange è relativo a qualcosa di altro, come ad
>esempio Item. Matrice di cui non sappiamo nulla. Se vuoi un aiuto
>fai un bel debug e facci sapere su quale riga hai l'errore. ok?
>
>Ciao!
>Alx81 =)
>
>http://blogs.dotnethell.it/suxstellino
>http://mvp.support.microsoft.com/profile/Alessandro.Alpi
>http://italy.mvps.org

Infatti la query è corretta, l'errore arriva proprio quando voglio riempire la textbox con il valore del reader relativi alla colonna "ESISTENZA"

Form1.textbox2.Text = dr.item("ESISTENZA") '

IL nome del campo è scritto correttamente, anche inserendo il valore dell'indice (in questo caso 4, il risultato non cambia).

Mi scuso se sto approfittando troppo della vostra disponibilità e competenza.

Ciao

alx_81 Profilo | Guru

>Infatti la query è corretta, l'errore arriva proprio quando voglio
>riempire la textbox con il valore del reader relativi alla colonna
>"ESISTENZA"
>
>Form1.textbox2.Text = dr.item("ESISTENZA") '
Questo va in errore perchè hai messo come alias RST, quindi diventa:
Form1.textbox2.Text = dr("RST")

>IL nome del campo è scritto correttamente, anche inserendo il
>valore dell'indice (in questo caso 4, il risultato non cambia).
il nome è RST, quello dell'alias, l'indice è 0, perchè è il primo campo della collezione degli items del dr.

>Mi scuso se sto approfittando troppo della vostra disponibilità e competenza.
ma figurati, è solo che devi capire anche noi che dobbiamo provare a capire il problema
Alx81 =)

http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

albedo Profilo | Junior Member

Funziona alla grande,

Grazie alx.

Poi magari più in la' ti disturberò ancora...

Dici che dovrei usare ExecuteScalar? Ma poi riesco a fare sempre un controllo circa l'esistenza o meno di un record? (HasRows).

Ciao e grazie ancora di cuore.

alx_81 Profilo | Guru

>Grazie alx.
Di nulla!

>Dici che dovrei usare ExecuteScalar? Ma poi riesco a fare sempre
>un controllo circa l'esistenza o meno di un record? (HasRows).
ExecuteScalar ti ritorna, come si capisce dal nome, uno scalare, e quindi un valore.
Se il valore non esiste ti torna un NullReference. Non puoi controllare la proprietà HasRows, che è del DataReader solamente (non puoi chiederti se uno scalare ha o meno righe ).
Il controllo se le righe esistono o meno non ti serve ogni qual volta cerchi di ritornare funzioni di aggregazione. la MIN ad esempio, se non esiste il o i record ti tornerà una colonna col valore NULL al suo interno, ma la colonna (che poi sarà il tuo scalare) ti torna sempre. Fai attenzione piuttosto a gestire il null. Se la condizione di WHERE non ti trova nessun record la tua MIN ti restituirà una colonna NULL. In quel caso, puoi gestire la cosa direttamente su DB. Ad esempio, in sql server puoi usare la funzione ISNULL:

SELECT ISNULL(MIN(Esistenza),0) AS RST FROM Giacenza WHERE Fornitore = 'xxx' AND Articolo = 10

In questo caso se hai null come risultato della MIN, otterrai un campo con il valore 0 (zero).
Così da codice non avrai problemi di gestione.

Ciao!
Alx81 =)

http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

albedo Profilo | Junior Member

[Un paio di ultime curiosità:

La differenza tra ExecuteReader ed ExecuteScalar, sta nel fatto che il Reader dve necessariamente leggere ogni singolo campo di una tabella prima di giungere ad una conclusione, metre lo Scalar interrompe il ciclo nel momento in cui intercetta il primo valore utile?

Se è così allora lo Scalar è conveniente usarlo nei casi in cui si abbiano miglia di record, ma interessa estrapolarne solo uno...
e poi in cho ordine andrebbe a "scalare" i record dal primo all'utlimo (allora suppongo non ci sarebbe grossa differenza con un Reader) o dall'ultimo al primo?

Che significa parametrizzare le query per evitare le SQL iniection? Suppongo sia qualcosa del genere: inserisco per errore in un campo il carattere * oppure un'apice e così otterrei un errore... certo tutto è gestibile mediante try-->Catch, ma il record sarebbe comunque compromesso.

UN'ultima cosa, e ti prego non chiamarmi seccante:

se uso lo ExecuteScalar, poi come faccio ad evidenziare il risultato nella textbox?

Ciao e grazie ancora

alx_81 Profilo | Guru

>La differenza tra ExecuteReader ed ExecuteScalar, sta nel fatto
>che il Reader dve necessariamente leggere ogni singolo campo
>di una tabella prima di giungere ad una conclusione, metre lo
>Scalar interrompe il ciclo nel momento in cui intercetta il primo
>valore utile?
L' ExecuteScalar torna la prima colonna della prima riga. L' ExecuteReader torna un DataReader e quindi un resultset.
>
>Se è così allora lo Scalar è conveniente usarlo nei casi in cui
>si abbiano miglia di record, ma interessa estrapolarne solo uno...
>e poi in cho ordine andrebbe a "scalare" i record dal primo all'utlimo
>(allora suppongo non ci sarebbe grossa differenza con un Reader)
>o dall'ultimo al primo?
L'ExecuteScalar si usa quando sai che la query ti torna un solo valore. Se hai più righe o più colonne, le scarta.
Quindi è inutile in quel caso.

>Che significa parametrizzare le query per evitare le SQL iniection?
E' un mondo a se. Se tu concateni le stringhe SQL rischi di ottenere potenziali istruzioni dannose.
Leggi qui:

SQL Injection
http://en.wikipedia.org/wiki/SQL_injection

>Suppongo sia qualcosa del genere: inserisco per errore in un
>campo il carattere * oppure un'apice e così otterrei un errore...
>certo tutto è gestibile mediante try-->Catch, ma il record
>sarebbe comunque compromesso.
no, peggio, potrebbero essere creati comandi molto più dannosi, sia per l'integrità del tuo db, sia per la logica applicativa.
Pensa ad una query come quella nel link, utilizzata come login.. un utente entrerebbe nell'area riservata del tuo sito senza sapere lo username.. molto dannoso.

Quindi utilizza le query parametriche. Ovvero le query con i parametri indicati nella stringa sql (ad esempio @param1 per sqlclient e ? per oledb) e definiti nell'oggetto command.
>
>se uso lo ExecuteScalar, poi come faccio ad evidenziare il risultato nella textbox?
cosa intendi evidenziare??

Alx81 =)

http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

albedo Profilo | Junior Member

>>se uso lo ExecuteScalar, poi come faccio ad evidenziare il risultato nella textbox?
>cosa intendi evidenziare??

Il nome di un fornitore, ad esempio.
Vorrei che mi riportasse questo 'valore' nella tesxtbox2...

Grazie axl, gentile e preparato come al soliro.

alx_81 Profilo | Guru

>Il nome di un fornitore, ad esempio.
>Vorrei che mi riportasse questo 'valore' nella tesxtbox2...
non hai visto l'esempio delle prime risposte? c'è tutto lì..
>
>Grazie axl, gentile e preparato come al soliro.
grazie, non c'è di che

Alx81 =)

http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org

albedo Profilo | Junior Member

>non hai visto l'esempio delle prime risposte? c'è tutto lì..

Ooops... pardon.

Chiudo qui il post

E' stato tutto preziosissimo.

Un bacio.

alx_81 Profilo | Guru

>E' stato tutto preziosissimo.
>Un bacio.
oddio.. tu sei un masculo..
una stretta di mano!

Alx81 =)

http://blogs.dotnethell.it/suxstellino
http://mvp.support.microsoft.com/profile/Alessandro.Alpi
http://italy.mvps.org
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