Newsgroup: it.comp.lang.visual-basic
Titolo: cursori con ADO e access

Ciao,
ho un problema strano: il pezzo di codice che allego non mi carica nessun
record dal db se imposto cursortype=adOpenDynamic, mentre funziona
correttamente se imposto cursortype=adOpenKeyset. Come si spiega questo
fatto?
Io ho bisogno che più utenti possano accedere contemporaneamente al db e
vedere reciprocamente le modifiche e le aggiunte effettuate. Questo può
avvenire anche usando adOpenKeyset? Mi pare di aver letto nella guida che
ciò è possibile solo usando adOpenDynamic.
Grazie e ciao.
    subCon = New ADODB.Connection
    Set subCmd = New ADODB.Command
    Set subRs = New ADODB.Recordset
    Set subCon = getConnection
    subCmd.ActiveConnection = subCon
    'cerco i riferimenti e li inserisco nella grid
    subCmd.CommandText = "select
a.id
,a.rappresentante,a.responsabile,a.ragsoc, " & _
                         " a.sede,a.citta,a.prov,a.cap,
a.tel
,a.fax, " & _
                         "a.lavorazioni,a.tecnici,a.op1,a.op2,a.op3,a.op4
from subappalto a, subappalto_anagrafica b, " & _
                         " anagrafica c where 
a.id
=b.subappalto_id AND " & _
                         " 
c.id
=b.anagrafica_id AND 
c.id
=?"
    'subRs.CursorType = adOpenKeyset
    subRs.CursorType = adOpenDynamic
    subRs.LockType = adLockOptimistic
    setParameter subCmd, txtCli.Text, adVarChar
    subRs.Open subCmd
    subRs.MoveFirst
End Sub

 nella guida che ciò è possibile solo usando adOpenDynamic.
Direi che basta il keyset, il dynamic dovrebbe "riprodurre" anche le
eliminazioni.
Però un minuto: anche con uno Static puoi vedere quello che è lo stato del
db, nel momento in cui viene composto il recordset. Gestire un recordset
dinamico (k o d che sia), credimi, è veramente laborioso, nel senso che ti
cambia sotto i piedi mentre ci stai lavorando sopra, anche solo scorrendolo.
Sicuro-sicuro che vuoi questo?


Il programma deve supportare diversi utenti contemporaneamente, i quali
accedono tutti al db e lo possono modificare.
Quindi ho bisogno per forza di farmi cambiare il db sotto i piedi :-(
Facendo alcune prove ho visto che se aggiungo nuovi record, con adOpenKeyset
questi nuovi aggiunti non vengono visti finché non interrogo nuovamente il
recordset (chiudendo e riaprendo la connessione e non solo il recordset).
Le modifiche a record esistenti vengono invece viste in tempo reale.
Con adOpenDynamic invece ho sempre il "problemuccio" che non mi carica una
mazza...

 carica una mazza...
Fai quella prova (senza l'uso di parametri) che ti consigliavo, col db fermo
e sicuro che la tua where includa qualcosa...

 
http://makeashorterlink.com/?V2E841C77
E anche questo:
http://makeashorterlink.com/?T23952C77


Ho trovato l'intoppo: in effetti il problema era sul refresh delle maschere
dati:
la mia procedura di refresh, inizialmente pensata per un cursore di tipo
keyset,
faceva un controllo del tipo: if rs.recordcount<>0 then....
solo che quel recordcount era sempre -1 !!!
Ho sostituito con un bel "if not rs.eof" e ora gira bene.
Ora devo solo decidere se rischiarmela coi cursori dinamici o prendermela
un po' più tranquilla.
Bella discussione, comunque :-)
Bye!

 prendermela un po' più tranquilla.
Leggi l'altro link che ti ho dato e, se non sei masochista, sceglierai la
seconda (Static 4ever!)

 Avevo dei dubbi, infatti. Perň mi restano e approfondisco... ;-)
Sě, hai ragione:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsentpro/ht
ml/veconkeysetdrivencursors.asp


Nel caso di un contatto nell'anagrafica nel mio caso è plausibile che due
operatori si trovino ad un certo punto a dover inserire la stessa azienda e
ti spiego perché:
supponiamo di avere un cursore statico e due operatori umani A e B che hanno
il programma già aperto, e che l'operatore A abbia inserito la Rossi SPA in
anagrafica. L'operatore B deve elaborare un documento per la Rossi SPA e la
cerca nell'anagrafica, ma non la trova perché il cursore statico non ha
visto le aggiunte inserite dall'operatore A .
Chiaro che a questo punto devo trovare un modo per non costringere
l'operatore B a richiedere un aggiornamento del recordset ogni volta che
deve scorrere i record dell'anagrafica. Non credo che sia una buona idea
ricaricare il recordset ad ogni pressione del tasto "avanti" o "indietro", e
questo è l'unico ostacolo che mi frena dall'utilizzare un cursore non
dinamico; d'altra parte, sebbene abbia molti anni di esperienza in ambiente
web, questo è il mio primo programma multiutente tradizionale e sono un po'
carente di esperienza. Sul web è tutto molto più facile.

carente di esperienza. Sul web č tutto molto piů facile.
Prova a portare sul desktop l'esperienza maturata sul web: otterrai
un'applicazione multiutente davvero scalabile. Pero' levati di dosso
Access, quello ti taglia le mani.
-- 
ciao,
hal

[Generale Cluster = 
alexunsa...@unsampdorianosoftmasters.net
 in
c1afic$o2q$
1...@newsreader.mailgate.org
] ha scritto:


Quoto tutto solo per dire: guarda che questo accade in ogni azienda che
debba creare nuovi clienti/fornitori e persino articoli, oltre che
documenti. Non c'è nulla di nuovo, sempre di gestionali stiamo parlando...
Dimmi: qual è la sostanziale differenza fra un cursore dinamico o statico,
in tal senso?
Non devi essere tu, comunque tu (per esempio con l'ipotesi che ti ho
riassunto prima), che devi stabilire se una cosa c'è o non c'è?
Se tu fai una:
Select * From Clienti Where Codice='pippo'
oppure, anche,
Select * From Clienti Where PartitaIVA='
12345678901
'
oppure, ancora,
Select * From Clienti Where RagioneSociale='Rossi SpA'
dimmi, qualunque cursore tu usi e indipendentemente dal tipo di database
(vecchia "guerra" con hal e altri) cosa conta il dynamic o lo static? Non
conta di più (e, io aggiungo/suggerisco, solo!) quando tu fai questa Select?
Ripeto, nulla conta il tipo di cursore o di database, conta come si
implementa la realizzazione delle necessità e, in un impeto di presunzione,
questo "come" è sempre uguale, ovunque. No, non ho detto perfetto, dico che
dovendo scegliere si sceglie la strategia migliore (operativamente
parlando), o, se preferisci, la meno peggio.

 Access, quello ti taglia le mani.
D'accordissimo con la prima frase, ripeto in "non c'azzecca" per la seconda.

 esperienza. Sul web è tutto molto più facile.
Ehm, ma come gestivi la concorrenza nel web?

 Ehm, ma come gestivi la concorrenza nel web?
Poi vado via prima che mi si meni...
Con l'ID autoincrementante, vero?!
Ecco, se anche possibile, dimentica i campi autoincrementanti. E' solo un
consiglio, eh?!
Si impastano, creano problemi (pensa a duplicazioni, trasferimenti da e per
altri db e a passaggi d'anno).
Sono tranquillamente emulabili con dei campi (uno o 10) che garantiscano
univocità di ogni record (ogni singolo record!) e, è bene specificarlo, che
corrispondano a un indice (almeno uno per ogni tabella) con chiave univoca.

 Ehm, ma come gestivi la concorrenza nel web?
sul web si ragiona in maniera transazionale e non ci sono connessioni che
rimangono aperte per più di quei 500-1000 ms al max
Forse è solo questione di abitudine, io mi sono formato in ambito web e
magari sono un po' ancorato ai miei schemi mentali.


Qui non mi sento di concordare con te.
Di certo sul web non ho lavorato con aScess, ma ho avuto la fortuna di
utilizzare DBMS più seri tipo Oracle, PostgreSQL, lo stesso MSSQL, e mySQL e
lì l'utilizzo di campi autoincrementanti, dove non presente (vedi oracolo e
postgre), si cerca di emularlo con trigger e sequence combinati tra loro.
Su questo posso andare tranquillo perché ho avuto come maestri alcuni tra i
più bravi DBA e software engineer sia italiani che stranieri.

hal, non c'azzecca 'na cippa. Scusa, eh?!
Mi sono espresso in modo incompleto.
Mi riferivo all'impatto sulle prestazioni provocato dalla frequente
esecuzione della stessa query. Con Access non si puo' sfruttare
qualche forma di caching dei dati per migliorare le prestazioni. 
Con Access la cache e' sul pc locale e rimane quindi all'oscuro di
quanto succede nel database.
Diverso sarebbe se nel backend ci fosse un database client-server: in
questo caso si sfrutterebbe la cache aggiornata del server, ottenendo
risposte molto piu' veloci, soprattutto in presenza di filtri nelle
query, anche con tabelle di grandi dimensioni.
-- 
ciao,
hal

[Generale Cluster = 
alexunsa...@unsampdorianosoftmasters.net
 in
c1al6m$vii$
1...@newsreader.mailgate.org
] ha scritto:

Come vuoi, anche per i trigger...

 che rimangono aperte per più di quei 500-1000 ms al max
Potrebbero essere 500-1000 ms di troppo.
Quel che si spera che non debba accadere, certamente accadrà nel momento e
caso più distruttivo...


Sgrat sgrat...   :-)
Premesso che non scrivevo applicazioni mission-critical o finanziarie sul
web e non le scrivevo certo in VB, però le transazioni ti mettono abbastanza
al sicuro da eventi catastrofici e in caso di errori se ti dimentichi di
gestire qualche situazione un bel rollback dentro un'exception ti para il
c**o se proprio non sai cosa fare. Comunque prevedere gli errori in
applicazioni web dove il codice segue un flusso preciso è meno problematico
che in un'applicazione desktop più ricca di funzioni.
Ora ti dò la buonanotte se no andiamo clamorosamente OT
Bye!