Newsgroup: it.comp.lang.visual-basic
Titolo: [?] Nuovo record e campo contatore: come determinarne il valore?

Un ipotetico DB si trova su un *server di una LAN*, ed al suo interno si trovano due
tabelle, una collegata all'altra:
La tabella [persone] con la seguente struttura
[id]: contatore
[nome]: testo
e la tabella [amici] con la seguente struttura:
[id-persona]: numerico
[da quanto tempo]: numerico
dove il campo [id-persona] e' collegato da una relazione "uno a uno" con il campo [id]
della tabella [persone].
In pratica nella tabella [amici] posso determinare quali siano le persone che sono anche
"amici" tramite una relazione "Is-A"
#Scopo#: inserire un nuovo "amico".
#Domanda#: qual'e' il modo piu' *efficiente* per inserire un nuovo record nella tabella
[persone] ed ottenere il valore del campo [id] assegnato automaticamente al nuovo record
per poter cosi' aggioranre la tabella [amici]?
Nel cosiderare una soluzione *efficiente*, tenete in conto che il database viene acceduto
da un computer client, e che quindi non si vuole sovraccaricare la rete di traffico
inutile...
Qualcuno sa rispondermi?
########################## Soluzione1
Moreno Sirri aveva proposto di sostituire il campo contatore con un campo numerico e di
calcolare ogni volta il valore massimo con la query
SELECT Max([persone].[ID]) AS [Ultimo] FROM [persone]
Altre soluzioni?

Le soluzioni finora trovate:
Soluzione 1) - Scartata per possibili errori in multiutenza
Sostituire il campo contatore con un campo numerico e calcolare ogni volta il valore
massimo con la query
    SELECT Max([persone].[ID]) AS [Ultimo] FROM [persone]
Se due utenti eseguono (quasi) contemporaneamente la query otterranno lo stesso numero per
il nuovo indice (si potrebbe risolvere rieseguendo la query che trova il Max dopo
l'errore).
Soluzione 2) - Scartata per possibili errori in multiutenza
Aprire la connessione, aprire il recordset, aggiungere il record, effettuare una requery e
leggere l'ultimo record (che pero' in multiutenza non e' detto che sia quello appena
inserito: poco prima della requery un altro utente inserisce un record che diventa
l'ultimo della tabella!).
Soluzione 3) - Inefficiente
Eseguo una query che mi cerchi quel record che abbia i campi uguali proprio a quei valori
appena inseriti: ma questa e' estremamente inefficiente se nel DB ci sono migliaia di
records...

 il nuovo indice (si potrebbe risolvere rieseguendo la query che trova il
Max dopo
[...]

 e lascia gestire i contatori ai DBMS, che lo fanno meglio di noi.
Ti ringrazio delle delucidazioni, in parte avevo letto qualcosa sull'MSDN proprio in
questi giorni.
Il problema di recuperare l'ultimo ID inserito da ADO e' proprio il problema che intendo
risolvere! Non tutte le soluzioni che mi sono state proposte pero' funzionano, alcune
aggirano il problema senza risolverlo ed introducendo altre falle, altre sono estremamente
inefficienti...
Provero' a fare ricerche sull'autonumber di Access (ma per caso non sarà il campo
contatore?).
Finora pero' non ho trovato una soluzione che funzioni... :(

 > atomica. Questa semplice parolina magica significa che PUOI STARE SICURO
che
[...]

Grazie! Le prove fatte finora erano con un cursore lato client (e non andava). Sto facendo
delle prove coi cursori e per motivi di efficienza, durante l'update mi serve
assolutamente un cursore lato server (con quello lato client, l'apertura del recordset
impiega alcuni secondi su una tabella con 8000 records, mentre e' pressocche' immediata
con un cursore lato server).
Ha funzionato cosi' (finalmente!!!!!!!!!!!):
sub Add()
  Set conn = New ADODB.Connection
  conn.CursorLocation = adUseServer
  conn.Open strConnect
  recset.CursorLocation = adUseServer
  recset.Open "[persone]", conn, adOpenKeyset, adLockPessimistic, adCmdTable
  With recset
    .AddNew
    .Fields("nome") = txtName.Text
    .Update
    Debug.Print .Fields("id") ' qui stampa il codice del nuovo ID
  End With
  recset.Close
  Set recset = Nothing
  conn.close
End Sub
Il problema adesso e' la multiutenza... il cursore lato server e' condiviso?