Selezionare "a mano" l'ID di una tabella MSAccess

martedì 09 agosto 2005 - 23.58

astroman Profilo | Junior Member

Sembra pazzesco ma anche le cose più facili sembrano diventare un incubo con MSAccess 2003...

Ho una semplice tabella, necessito di crearmi "a mano" l'ID del record che vado a creare...nulla di più semplice...difatti ho creato il metodo come segue...

public static int CreateID()
{
int v=1;
string tmp=string.Empty;
OleDbConnection con=new OleDbConnection(Connection.Active());
con.Open();
OleDbCommand cmd=new OleDbCommand("SELECT Max(ID)+1 FROM TBL",con);
tmp=cmd.ExecuteScalar().ToString();
if (tmp!="")
{
v=Int32.Parse(tmp);
}
cmd.Cancel();
con.Close();
return v;
}

Niente di più semplice no?Il problema risulta alquanto assurdo solo a pensarci...in pratica io eseguo un loop, tabella vuota, inserisco il primo valore e riga nel DB, con il suo ID uguale a 1 senza problemi...iniziare a fare il 2ndo giro e...beh mi da errore e mi dice che sto provando ad inserire un valore duplicato!In pratica, facendo dei test, è risultato che al secondo giro lui cerca di inserire sempre 1!Al terzo giro del loop invece inizia a funzionare...
Ma sono impazzito io...o sto sbagliando qualcosa?!?
E' perchè ho creato un metodo statico per caso?

Cteniza Profilo | Guru

La cosa più semplice che puoi fare è togliere l'automatismo sull'assegnazione dei numeri, non c'è nulla di male nel farlo.
Se proprio non te la senti :)) di togliere l'autonumber fai in modo che parta da un numero molto grande es: 100000 così quando assegnerai (in variazione) il numero che deve avere non ci sarà possibilità di conflitto.
Se decidi per questa strada ti consiglio di lasciare che numeri automaticamente il record e poi variare il codice con il tuo numero.



astroman Profilo | Junior Member

Si,ho sempre deciso di non usare l'autonumber su tabelle in cui avevo bisogno di movimentare molto i record: il problema (testato fino alle 2 di notte...) è che sembra che se metto questo metodo su uno struct e lo creo come static non venga distrutto...
Hai idee per come farlo funzionare?O faccio prima a crearmi una classe pubblica e creo un metodo pubblico?

Cteniza Profilo | Guru

Prova a cambiare metodo:
public static int CreateID()
{
int v=0;
OleDbConnection con=new OleDbConnection(Connection.Active());
con.Open();
OleDbCommand cmd=new OleDbCommand("SELECT Max(ID)+1 FROM TBL",con);
OleDbDataReader dr = cmd.ExecuteReader();
if (dr.Read())
v = dr.GetInt32(0);
dr.Close()
cmd.Cancel();
con.Close();
if (v == 0)
v++;
return v;
}


astroman Profilo | Junior Member

Si, questo è stato il mio stesso tentativo, uguale identico!:D
Il risultato è stato alquanto sconcertante...poichè se io vado in debug(inserendo un breakpoint) và alla perfezione passando riga per riga...se lo lascio andare in esecuzione per i fatti suoi và in errore, mi torna un errore dal DB affermando che sto cercando di inserire 2 righe duplicate!!!
Ho fatto la prova(testardo come sono..) di togliere la chiave primaria sull'ID numerico intero lungo (che sia per questo tipo di dato che và in errore...boh..) ed effettivamente mi scrive 2 volte "1" e poi "2" sul terzo record (ho solo 3 record al momento da inserire)...
Sono pazzo io...o è un bug di MS.Net 2003?:D

astroman Profilo | Junior Member

Si, questo è stato il mio stesso tentativo, uguale identico!:D
Il risultato è stato alquanto sconcertante...poichè se io vado in debug(inserendo un breakpoint) và alla perfezione passando riga per riga...se lo lascio andare in esecuzione per i fatti suoi và in errore, mi torna un errore dal DB affermando che sto cercando di inserire 2 righe duplicate!!!
Ho fatto la prova(testardo come sono..) di togliere la chiave primaria sull'ID numerico intero lungo (che sia per questo tipo di dato che và in errore...boh..) ed effettivamente mi scrive 2 volte "1" e poi "2" sul terzo record (ho solo 3 record al momento da inserire)...
Sono pazzo io...o è un bug di MS.Net 2003?:D

astroman Profilo | Junior Member

Si, questo è stato il mio stesso tentativo, uguale identico!:D
Il risultato è stato alquanto sconcertante...poichè se io vado in debug(inserendo un breakpoint) và alla perfezione passando riga per riga...se lo lascio andare in esecuzione per i fatti suoi và in errore, mi torna un errore dal DB affermando che sto cercando di inserire 2 righe duplicate!!!
Ho fatto la prova(testardo come sono..) di togliere la chiave primaria sull'ID numerico intero lungo (che sia per questo tipo di dato che và in errore...boh..) ed effettivamente mi scrive 2 volte "1" e poi "2" sul terzo record (ho solo 3 record al momento da inserire)...
Sono pazzo io...o è un bug di MS.Net 2003?:D

Cteniza Profilo | Guru

Potrebbe essere anche il problema dato dai secondi di latency per la scrittura della cache.
Prova a mettere una pausa di 5 secondi (latenza di default), se funziona devi togliere il parametro.


astroman Profilo | Junior Member

Ah...interessante...questa proprio non la sapevo!:-)
Mi potresti dare uno spunto?Come potrei metterlo in pratica la "pausa" di 5 sec?Non ne avrei idea al momento...

astroman Profilo | Junior Member

E a che parametro ti riferisci?

astroman Profilo | Junior Member

Beh ho preferito (giustamente) arrangiarmi...hai ragione, funziona alla perfezione!!!
Nello struct ho messo:

static TimeSpan waitTime = new TimeSpan(0,0,0,0,5);

e prima di sparare fuori all'utente il valore:

Thread.Sleep(waitTime);

(ho importato il System.Thread)
Incredibile ma vero...ma era proprio questo!Pazzesco...

Cteniza Profilo | Guru

Avevo un appunto (e l'ho anche scritto in un mio programma) riguardo a quel parametro.
Si può impostare in due modi.
1) nel registro
2) inserendo un valore sulla stringa di connessione
Se trovo l'appunto o il programma te lo comunico, intanto tu potresti andare ad indagare su google, il valore di default è 5000 (millisecondi) aspetta quindi per ben 5 secondi.


astroman Profilo | Junior Member

ma così come ho scritto io, però...ho rifatto il test e non funziona...e l'applicativo diventa lentissimo...
mi sa che dev'essere nella stringa...

astroman Profilo | Junior Member

No, niente da fare...anche se metto 5 secondi và in errore...non capisco...

astroman Profilo | Junior Member

Finalmente ho trovato la soluzione a questo problema assurdo!
In pratica si incasinava tutto perchè io ho un loop di datarow di un datatable con logicamente la sua connessione e poi chiamavo al suo interno il metodo statico: praticamente c'era un disalineamento di sincronizzazione tra la connessione aperta dal datarow e quello del metodo statico per trovare l'ID a mano.
La soluzione?
Beh semplice: alla fine gli passo al metodo statico la stessa connessione che utilizza il datarow e tutto fila alla perfezione!Ti posto quanto segue e vorrei una tua impressione in merito se pensi che si possa migliorare:

public static int CreateID(OleDbConnection cnx)
{
int v=0;
OleDbCommand cmd=new OleDbCommand("SELECT Max(ID)+1 AS NewID FROM TBL",cnx);
OleDbDataReader dr=cmd.ExecuteReader();
dr.Read();
if (dr["NewID"].ToString()!="")
{
v=Int32.Parse(dr["NewID"].ToString());
}
else
{
v=1;
}
cmd.Cancel();
dr.Close();
return v;
}

Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2023
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5