Newsgroup: it.comp.lang.delphi
Titolo: Ultimo ID access

Salve,
il mio problema è questo, dopo l' INSERT in una tab access ho la
necessità di recuperare l'ID autoincrementale generato dal database.
Ho guardato un pò nei vecchi post ma tale funzione sembra un pò ostica
x access, al contrario si può fare con mysql e db superiori.
Ho anche trovato su msdn questo articolo
http://support.microsoft.com/kb/815629
Volevo sapere se qualcuno aveva già avuto tale necessità.
Grazie Andrea

 necessità di recuperare l'ID autoincrementale generato dal database.
Non ricordo se access ha i trigger (ne dubito fortemente) o se sia 
possibile interrogare direttamente i generator... ad ogni modo dopo la 
INSER esegui una query tipo:
SELECT MAX(nomecampoID) from tua tabella
e ricavati l'ID in questo modo.
Ciao
-- 
Morde

 ha scritto nel messaggio 
news:0272bbd5-dba0-4e8d...@g38g2000yqd.googlegroups.com...


<%
set rs = Server.CreateObject("ADODB.Recordset")
SQL = "SELECT TOP 1 ID FROM xxxxxx ORDER BY ID DESC" ' mi leggo l'ID del 
record appena inserito
rs.Open sql, Conn_STRING
ultimo_ID = rs("ID")
rs.Close
set rs = nothing
Response.Write(ultimo_ID)
%>
ti capisco perchè c'ho appena tribolato
C. 


E' quello che faccio ora nella mia applicazione ma non mi rende
sicuro.
In multiutenza, potrei avere sui client inserimenti contemporanei
(difficile ma non impossibile) e a quel punto potrei recuperare
erroneamente lo stesso ID (cioè l'ultimo) per tutti e due i client.
c1 INSERT
c1 MAX
c2 INSERT
c2 MAX
così è OK
ma se ho
c1 INSERT
c2 INSERT
c1 MAX
c2 MAX
qua recupero lo stesso id x i due client

 C.
Credo che con TOP recupero comunque il MAX ID
e a questo punto ho il problema che ho esposto a Morde
sbaglio?

Sto provando con
SELECT @@IDENTITY FROM tabella
dopo che ho fatto l'INSERT.
Sembra funzionare, ma ho il dubbio che non faccia altro che quello che fa il 
MAX, ossia ritornarmi l'ID massimo e non quello relativo all'INSERT
Che ne dite?

 qua recupero lo stesso id x i due client
Se n campi di danno una chiave univoca puoi fare
SELECT nomecampoID from tua tabella where campoA=a, campoB=b, campoC=c ...
^_Goblin_^
-- 
Ibis et redibis non morieris in bello
http://goblinland.myminicity.com/

 erroneamente lo stesso ID (cioè l'ultimo) per tutti e due i client.
Non ricordo proprio, ma su Access si può bloccare le tabelle?
Se sì, il problema è risolto.
1) Blocchi la tabella da lettura/scrittura.
2) Esegui il tuo insert
3) con Select Max(ID) trovi l'ultima id inserita
4) Sblocchi la tabella
Il tutto si basa sull'atomicità dell'operazione, che non produce 
rallentamenti sensibili. 

 Se sì, il problema è risolto.
In passato avevo postato decine di volte su questo ng riguardo il lock 
di access, cercate "morde access lock" (Per fortuna ho abbandonato quel 
"database" per passare a migliori lidi...)
Condivito quello che scrivi.
Ad ogni modo, una piccola e forse inutile considerazione: se possibile, 
EVITATE di usare access per soluzioni multiutenza, perchè ha delle 
forti limitazioni sugli accessi concorrenziali.
Molto ma molto meglio database sql free quali interbase firebird, 
sqlite,mysql,e i fratelli maggiori db2, sqlserver e oracle, le quali 
case madri per motivi di concorrenza negli ultimi anni hanno reso 
disponibili delle versioni free (definite express). Io le ho usate per 
progetti di produzione, e devo dire che mi sono trovato bene, 
sopratutto con sql server 2005 express. (ho provato anche db2 e devo 
dire che viaggia anche meglio, solo che microsoft in fatto di 
interfacce (db manager) e' imbattibile)
-- 
Morde

 e ricavati l'ID in questo modo.
molto pericoloso.
in multiutenza, non hai la certezza che il max sia l'id generato dal
client A e non dal client B.
A.

esatto.
A.

 MAX, ossia ritornarmi l'ID massimo e non quello relativo all'INSERT
Secondo me, ti conviene postare su qualche ng dedicato ad access.
A.


In effetti sto pensando di passare a sql express 2008.
Visto che tu l'hai usato che eventuali problemi di distribuzione
potrei avere? In pratica cosa dovrei installare sul server del
cliente? Ho vista che la versione base è comunque di 100 MB.
Ciao

 Ho anche trovato su msdn questo articolohttp://
support.microsoft.com/kb/815629
Forse mi sono perso qualcosa, ma non mi pare un grosso problema, visto
che access gestisce le transazioni:
// apri la transazione
ADOConnection.BeginTrans;
// qui fai la tua insert
// . . .
// ora fai la select del TOP ID
SELECT TOP 1 ID FROM xxxxxx ORDER BY ID DESC"...
// ...
// infine fai il commit di tutto
ADOConnection.CommitTrans;
Ovviamente l'isolation level della transazione deve essere
"ilCursorStability", ma questo, guarda caso, è il valore di default!
Ciao,
Gp

Forse mi sono perso qualcosa, ma non mi pare un grosso problema, visto
che access gestisce le transazioni:
Access gestisce le transazioni???
L'avevo escluso a priori, ora controllo.
Grazie 

 Ciao
Lo scarichi e lo installi cosi' come te lo danno. Se occorrono dei 
prerequisiti (vedi .net framework) te lo chiedera' il setup.
Vai su microsoft sulla pagina di sql server 2008 e vedi i download 
effettuati, i piu' frequenti.
Ciao
-- 
Morde

Ovviamente l'isolation level della transazione deve essere
"ilCursorStability", ma questo, guarda caso, è il valore di default!
Sembra funzionare.
Mi è sorto un dubbio però. Come imposto la cursorlocation dell' 
AdoConnection ?
di default è clUseClient, va forse settata cluseserver?
Posso poi tenere il lock ltOptimistic della AdoQuery? 

 Posso poi tenere il lock ltOptimistic della AdoQuery?
Lock diversi ti servono solitamente quando usi ADOQUERY per fare
DELETE o UPDATE.
Ciao,
Gp

Ok, ciao e grazie.
Andrea