Newsgroup: it.comp.software.database
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...
########################## Soluzione1
Uno del newsgroup it.comp.lang.visual-basic 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]
Qualcuno ha altre soluzioni?
Grazie...
PS: uso Access e ADO in VB...

 wrote in message
d2jA6.11759$k53.2...@news1.tin.it...


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... (grazie comunque DELU)

 PS: uso Access e ADO in VB...
Hai provato cosě?
   with recset
      .AddNew
      !campo1 =  <valore>
      !campo2 =  <valore>
      .Update
      .Resync adAffectCurrent
      contatore = !id
   end with
Ciao, Marco

 PS: uso Access e ADO in VB...
Hai provato cosě?


 Ciao, Marco
Si, qualcosa di simile. Anziche' resync, faccio requery seguita da movelast (che non va in
multiutenza).
Comuque ho provato cosi':
sub Add()
  Set conn = New ADODB.Connection
  conn.CursorLocation = adUseServer
  conn.Open strConnect
  recset.CursorLocation = adUseClient
  recset.Open "[persone]", conn, adOpenKeyset, adLockPessimistic, adCmdTable
  'recset.Open "[persone]", conn, adOpenStatic, adLockPessimistic, adCmdTable
  With recset
    .AddNew
    .Fields("nome") = txtName.Text
    .Update
    .Resync adAffectCurrent
' qui mi segnala errore: il valore chiave della riga e' stato modificato o eliminato _
  nell'origine dati. La riga locale verrà eliminata.
    Debug.Print .Fields("id")
  End With
  recset.Close
  Set recset = Nothing
  conn.close
End Sub

>Il metodo Resync non è disponibile su un Recordset sul lato client.
Perciò (se il tuo db server te lo permette) prova a definire il cursore del
recset su lato server
Ciao, Marco

Ho trovato "una" soluzione... e pure efficiente.
Quello che ho fatto e' di impostare il cursore lato server e specificarlo di tipo
Keyset...
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?

Ho postato poco fa la soluzione... ed in effetti sono costretto ad usare un cursore lato
server di tipo Keyset (con uno dinamico non funziona, e gli altri non li ho provati).