Newsgroup: it.comp.lang.delphi
Titolo: TStoredProc asincrona: risultati e annullamento

Ciao a tutti,
 
ho la necessità di eseguire una Stored Procedure realizzata in Sql Server che restituisce dei risultati.
Visto che si tratta di un'elaborazione che potrebbe richiedere tempo ho pensato di eseguirla in modo asincrono in modo tale da permettere all'utente di annullare l'operazione e di vedere il tempo che passa.
 
Due problemi:
 
1. Pensavo di poter fermare la store procedure eseguendo il metodo .Close; in realtà non è così. Se provo a rieseguirla immediatamente fallisce.
2. Se lascio eseguire la store procedure il dataset risulta alimentato ma sulla DBGrid non compare nulla.
 
 
Utilizzando la store procedure in modalità sincrona i dati mi vengo restituiti correttamente.
 
Qualcosa ha idea di come risolvere i miei problemi?
 
grazie, saluti
L.

Sono TUTTI BRAVI a dire "la stored procedure la si esegue lato server, non genera traffico di rete e quindi e' piu' veloce".
Ma nessuno fa presente che se lato server esegui una stored procedure PESANTE, rischi di rallentare tutte le altre elaborazioni, salvo avere il motore db che gira su un server tosto.
 
 
 
La stored procedure è eseguita LATO SERVER.
Quindi, il client chiede al server la sua esecuzione e da li non sa un emerito kazzen di cosa succede o del relativo stato di avanzamento.
 
Puoi mettere un tadostoredproc in un thread (occhio, usando una tadoconnection specifica per il thread, altrimenti NON FUNZIONA) e distruggere il thread passate n unità di tempo, ma questo NON FERMA L'ELABORAZIONE LATO SERVER.
 
Il client di oracle (oci.dll) espone una funzione per interrompere una query lato server. Magari ne ha una anche per le stored procedure....?
Magari anche il client di SqlServer ha queste possibilità...?
Ovviamente (ma non per tutti) l'uso di queste funzionalità specifiche del database in genere non è possibile usando le tecnologie di accesso ai dati standard presenti in delphi ma tramite suite di terze parti, come i DOA per oracle.
 
 
Veniamo ora al tuo problema...
 
1) cosa si intende per "potrebbe richiedere tempo"?
Parliamo di 5 minuti, 3 ore, 2 giorni?
 
2) con quale frequenza avresti la necessità di eseguirla?
 
3) quale è l'ordine di grandezza della mole di dati?
 
A.

 3) quale è l'ordine di grandezza della mole di dati?
10, 20 o anche 40 mila record
 
Cmq non è ne il tempo nel la dimensione il mio problema.
Volevo solo capire se posso BLOCCARE una stored asincrona da delphi.
Il resto me lo sistemo io
 

 Volevo solo capire se posso BLOCCARE una stored asincrona da delphi.
 
Puoi solo mettere la chiamata alla stored procedure in un "qualcosa" di asincrono". Non esiste la stored procedure "asincrona".
 
Io valuterei un approccio diverso, ad esempio una o piu classi delphi che creano un consolidato che viene poi reso persistente in un clientdataset da dare in pasto ad una griglia o altro. Avresti molti vantaggi:
 
1) essendo delphi, puoi avere delle callback per mostrare lo stato di avanzamento ed interrompere l'elaborazione.
 
2) essendo lato client, faresti solo delle query, senza sovraccaricare il server per l'esecuzione di una stored procedure di cui potresti volere l'interruzione, cosa non prp semplice e che ti costringerebbe a mollar ado o dbx
 
3) non è detto che sia piu' lento rispetto alla stored procedure...
 
A.

 Volevo solo capire se posso BLOCCARE una stored asincrona da delphi.
 
Tu, dal tuo programma, lanci un'elaborazione che procede per i fatti 
suoi, e vuoi fermarla quando ti pare: questo architettura �, by design, 
difettosa. Non puoi conciliare due concetti asincroni per natura.
O il tuo programma aspetta, oppure trovi un'altra soluzione che 
disaccoppia i due contesti e li fa comunicare.
 
La soluzione � quella di anteporre un "mediatore" tra i due: quello che 
ti suggerisco � di crearti una tabella di mediazione che contiene le 
richieste dei client, dove ogni client che d� vita ad una elaborazione 
scrive un record di richiesta interruzione se necessario.
 
La tua stored procedure, durante l'elaborazione che immagino molto lunga 
e contenente tanti statements SQL, controlla periodicamente questa 
tabella, e se trova una richiesta di abort da parte del client che l'ha 
invocata, cancella la richiesta origine e interrompe la propria 
esecuzione, scrivendo in una tabella un log apposito.
 
Questa soluzione � quanto di pi� semplice si possa trovare senza 
appesantire troppo la tua architettura, perch� tiene separati i 
contesti: la stored vive nel contesto del DB e legge i messaggi a lei 
indirizzati sempre nel suo contesto.
Il client si comporta da tale: richiede esecuzione di job al DB e manda 
messaggi alle componenti del DB scrivendo su una semplice tabella.
 
Tutto questo pandemonio ;-) per mantenere l'asincronismo.
 
-- 
morde
Android
QT 4.7
Delphi (5,6,7.. expired)
Firebird Database
 

 2. Se lascio eseguire la store procedure il dataset risulta alimentato ma sulla DBGrid non compare nulla.
Probabilmente dipende dal timeout impostato nella connessione.
 
Nella mia risposta in coda al thread ti ho spiegato perch� non � 
possibile far parlare due elementi asincroni che vivono in contesti 
separati.
 
Dai un'occhiata e vedi se la cosa ti piace, e possiamo pure 
approfondirla ed estenderla se vuoi.


Grazie dei suggerimenti.
 
Alla fine ho ceduto e ho lasciato la Stored in asincrono (così l'utente vede il tempo che passa eh eh) però non permetto di bloccarne l'esecuzione.
 
La DBGrid non risultava aggiornata semplicemente perchè l'oggetto TDBGrid (e relativo DataSource) era gièà stato creato.
Se attendo la fine della stored procedure (StoredProc1.State <> dsBrowse) e poi creo gli oggetti il problema non si presenta.
 
Purtroppo non ho controllo sulla stored perchè è realizzata da un altro fornitore e non posso permettermi di modificarne i contenuti altrimenti avrei optato per una soluzione più comoda.
 
Come sempre grazie degli interventi
L.