Gaxx
Messages postés28Date d'inscriptionlundi 20 décembre 2004StatutMembreDernière intervention19 mars 2008
-
21 mars 2005 à 18:06
Allen912
Messages postés6Date d'inscriptiondimanche 8 janvier 2006StatutMembreDernière intervention26 mars 2006
-
6 mars 2006 à 11:05
Bonjour,
Dèrrière ce titre se cache un problème fréquent apparemment non résolu dans le forum :
Récupérer la valeur d'un champ en Numéro auto après une insertion dans une table (T_Contacts) pour aller lui associer des droits dans une table (T_Autorisations).
A une époque j'avais fait ça sous Oracle 9i via une procédure stockée mais là j'utilise Access 2003 ... Qui n'a pas l'air de gérer les procédures stockées, qui est cachotier quand aux noms de ses séquences, et dont l'aide ne m'aide pas vraiment pour ce problème ...
Donc voici la méthode choisie dans mon programme en C# :
Insertion dans T_Contacts
Récupération de la valeur maximale de T_Contacts.Id
Insertion dans T_Autorisations avec la valeur récupérée ci-dessus
Tel quel la valeur récupérée n'est pas forcément celle que je veut en cas d'insertions venant de plusieurs utilisateurs dans T_Contacts.
Pour sécuriser cette démarche j'utilise un System.Data.OleDb.OleDbTransaction. Il existe une énumération (IsolationLevel) à passer en paramètre de la méthode "BeginTransaction" mais j'ai pô tout compris et en essayant avec la valeur "ReadCommitted " je me suis fait jeter ...
Voici mon code actuel :
System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection(fAuth.getConnectionString());
System.Data.OleDb.OleDbCommand comm =
new System.Data.OleDb.OleDbCommand() ;
comm.Connection = conn;
conn.Open();
System.Data.OleDb.OleDbTransaction transaction;
transaction = conn.BeginTransaction();
comm.Transaction = transaction;
[Je construit mes requêtes et les exécute ...]
try
{
transaction.Commit();
}
catch(Exception ex)
{
try
{
transaction.Rollback();
}
catch (System.Data.OleDb.OleDbException exe)
{
if (transaction.Connection !=
null)
{
Console.WriteLine("An exception of type " + exe.GetType() +
" was encountered while attempting to roll back the transaction.");
}
}
Console.WriteLine("An exception of type " + ex.GetType() +
" was encountered while inserting the data.");
Console.WriteLine("Neither record was written to database.");
}
conn.Close();
Est-ce suffisant pour garantir que le T_Contacts.Id récupéré est bien celui que je veut ?
Gaxx
Messages postés28Date d'inscriptionlundi 20 décembre 2004StatutMembreDernière intervention19 mars 2008 22 mars 2005 à 12:13
Ok, j'ai fait le test et la requête "SELECT @@IDENTITY;" retourne la clef générée du dernier ajout dans une connexion donnée.
Donc le problème est résolu !
Il faut faire une requête d'insertion puis dans la même ouverture de connexion utiliser le "SELECT @@IDENTITY" pour récupérer la bonne valeur.
NB : L'utilisation de System.Data.OleDb.OleDbTransaction vérouille bien la table mais le fait un peu trop bien : aucune insertion parallèle n'est tolérée.
Le problème peut néanmoins être pallié via un try/catch avec un temps d'attente pour réessayer un peu plus tard lors de la libération de la ressource.
Gaxx
Messages postés28Date d'inscriptionlundi 20 décembre 2004StatutMembreDernière intervention19 mars 2008 22 mars 2005 à 11:03
Merci pour ta réponse mais j'avais déjà essayé ça sans succès : Access 2003 me jette en me disant "Caractères trouvés après la fin de l'instruction SQL" ...
Gaxx
Messages postés28Date d'inscriptionlundi 20 décembre 2004StatutMembreDernière intervention19 mars 2008 22 mars 2005 à 11:59
Est ce que la requête "SELECT @@IDENTITY;" retourne la clef générée du dernier ajout dans une connexion donnée, ou retourne-t-elle simplement la clef du dernier ajout toutes connexions confondues ?
Je m'explique :
- dans le premier cas je peut faire une nouvelle commande en étant sûr de récupérer la bonne valeur
- dans le second cas le problème reste entier
Vous n’avez pas trouvé la réponse que vous recherchez ?
Allen912
Messages postés6Date d'inscriptiondimanche 8 janvier 2006StatutMembreDernière intervention26 mars 2006 6 mars 2006 à 11:05
Bonjour,
Vous serait t'il possible de poster le code de construction et d'execution de votre requête. Je débute dans le system oledb et les transactions sont pour moi un mystère...
Votre exemple me permettrait de l'adapter à mon code...