IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VBA Access Discussion :

Controler les insertions avec les transactions


Sujet :

VBA Access

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 101
    Points : 64
    Points
    64
    Par défaut Controler les insertions avec les transactions
    Bonjour,

    J'ai un requête qui ajoute un enregistrement via DAO. Je souhaite après récupérer l'identifiant automatique le plus grand. J'ai une fonction GetMaxIdContact pour ca. Cependant il se peut que entre la requête d'insertion et la récupération de l'id maximum un autre enregistrement s'insère et dans ce cas ma fonction GetMaxIdContact ne me renvoi pas le bon identifiant.

    Peut on avec les transactions empêcher l'insertion de données pendant ce laps de temps.

    Voic mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    Private Sub enregistrerContact()
     
    Dim rst As DAO.Recordset
    Set rst = CurrentDb.OpenRecordset("SELECT * FROM contacts")
    rst.AddNew
    rst!titre_contact = titre_contact.Value
    rst!nom_contact = nom_contact.Value
    rst!prenom_contact = prenom_contact.Value
    rst!fonction_contact = fonction_contact.Value
    If (dateDeNaissance_contact.Value = "") Then
        rst!dateDeNaissance_contact = Null
    Else
        st!dateDeNaissance_contact = dateDeNaissance_contact
    End If
    rst!email_contact = email_contact.Value
    rst!tel_contact = tel_contact.Value
    rst!portable_contact = portable_contact.Value
    rst!fax_contact = fax_contact.Value
    rst!hobbies_contact = hobbies_contact.Value
    rst!note_contact = note_contact.Value
    rst.Update
    creerRelationClientContact
     
    End Sub
     
    Private Sub creerRelationClientContact()
     
    Dim rst As DAO.Recordset
    Set rst = CurrentDb.OpenRecordset("SELECT * FROM clients_contacts")
    rst.AddNew
    rst!id_client = Form_client.id_client.Value
    rst!id_contact = getMaxidContact
    rst.Update
     
    End Sub
     
    Private Function getMaxidContact() As Integer
     
    Dim rst As DAO.Recordset
    Set rst = CurrentDb.OpenRecordset("SELECT Max(id_contact) As maxIdContact FROM clients_contacts")
    getMaxidContact = rst!maxIdContact
     
    End Function
    Merci d'avance

  2. #2
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Bonjour,
    Citation Envoyé par robocop2776
    J'ai un requête qui ajoute un enregistrement via DAO. Je souhaite après récupérer l'identifiant automatique le plus grand.
    Pour être bien clair...
    Est-ce qu'il s'agit d'un champ de type "NuméroAuto" ou bien un champ que tu renseignes par toi-même avec ta fonction getMaxidContact.

    Cas 1. Un champ de type NuméroAuto

    Tu n'as pas besoin d'attribuer une valeur.
    C'est fait automatiquement.
    L'unicité est garantie par le moteur de bases de données.

    Cas 2. Une fonction détermine l'identifiant

    Ta fonction retourne la plus grande valeur d'identifiant déjà utilisée.
    Donc ici, tu dois incrémenter cet identifiant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Private Sub creerRelationClientContact()
    
    Dim rst As DAO.Recordset
    Set rst = CurrentDb.OpenRecordset("SELECT * FROM clients_contacts")
    rst.AddNew
    rst!id_client = Form_client.id_client.Value
    rst!id_contact = getMaxidContact + 1
    rst.Update
    
    End Sub
    Néanmoins, dans ce cas la transaction ne peut pas garantir que l'identifiant sera unique.
    Tout au plus, tu pourrais te protéger en mettant un "index unique" sur ce champ.
    En cas d'attribution d'un identifiant déjà utilisé, au moment d'entériner la transaction (Commit), une erreur se déclencherait en raison de la violation de la règle d'intégrité des données (identifiant unique).

    Mais franchement, cette approche ne me plaît pas beaucoup.
    _

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 101
    Points : 64
    Points
    64
    Par défaut
    J'ai du mal m'expliquer car en fait mon problème n'est pas l'attribution de mon identifiant mais sa récupération.

    En fait j'utilise le type numéroAuto de Access pour attribuer l'identifiant.
    Ma fonction "enregistrerContact" ajoute le contact dans la table. access lui attribue donc un identifiant unique via NuméroAuto. Seulement j'ai besoin de récupérer cette identifiant. Pour cela j'ai créer ma fonction "getMaxidContact()" qui récupère et me renvoi l'identifiant maximum. Cela marche très bien en mono-utilisateur mais si il y a plusieurs utilisateurs alors un problème se pose.

    Imaginons l'utilisateur A ajoute un contact. Il fait appel à la fonction enregistrer contact. Juste après un utilisateur B fait de même. Il se peut que l'enregistrement de l'utilisateur B soit insérer dans la base de données avant que l'utilisateur A ai récupérer l'identifiant de son enregistrement. Donc quand l'utilisateur A appelera la fonction "getMaxidContact()" il aura l'identifiant de l'utilisateur B car le plus grand.

    Exemple:

    Dans ce cas pas de pb:

    Utilisateur A : enregistrerContact (Access donne l'identifiant n° 10)
    Utilisateur A : getMaxidContact() renvoi 10
    Utilisateur B : enregistrerContact (Access donne l'identifiant n° 11)
    Utilisateur B : getMaxidContact() renvoi 11

    Dans ce cas il y a le pb:

    Utilisateur A : enregistrerContact (Access donne l'identifiant n° 10)
    Utilisateur B : enregistrerContact (Access donne l'identifiant n° 11)
    Utilisateur A : getMaxidContact() renvoi 11
    Utilisateur B : getMaxidContact() renvoi 11

    Dans ce cas est ce que les transactions permettrons de faire les fonctions enregistrerContact et getMaxidContact sans pouvoir être interrompu.

    J'espère que j'ai été clair.

  4. #4
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Citation Envoyé par robocop2776
    J'ai du mal m'expliquer car en fait mon problème n'est pas l'attribution de mon identifiant mais sa récupération.

    En fait j'utilise le type numéroAuto de Access pour attribuer l'identifiant.
    Ma fonction "enregistrerContact" ajoute le contact dans la table. access lui attribue donc un identifiant unique via NuméroAuto. Seulement j'ai besoin de récupérer cette identifiant. Pour cela j'ai créer ma fonction "getMaxidContact()" qui récupère et me renvoi l'identifiant maximum.
    En fait tu n'as pas besoin d'une fonction particulière.

    Il te suffit de récupérer l'identifiant au moment de l'insertion d'une nouvelle ligne dans la table [Contacts] et de transmettre cet identifiant à la procédure qui insère une ligne dans la table [clients_contacts]:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    Private Sub enregistrerContact()
        Dim rst As DAO.Recordset
        Dim idContact As Long
     
        Set rst = CurrentDb.OpenRecordset("contacts")
     
        rst.AddNew
     
        ' après AddNew, le champ de type NuméroAuto est immédiatement renseigné
        idContact  = rst!id_contact
     
        rst!titre_contact = titre_contact.Value
        rst!nom_contact = nom_contact.Value
        rst!prenom_contact = prenom_contact.Value
        rst!fonction_contact = fonction_contact.Value
        If (dateDeNaissance_contact.Value = "") Then
            rst!dateDeNaissance_contact = Null
        Else
            st!dateDeNaissance_contact = dateDeNaissance_contact
        End If
        rst!email_contact = email_contact.Value
        rst!tel_contact = tel_contact.Value
        rst!portable_contact = portable_contact.Value
        rst!fax_contact = fax_contact.Value
        rst!hobbies_contact = hobbies_contact.Value
        rst!note_contact = note_contact.Value
        rst.Update
     
        creerRelationClientContact idContact 
    End Sub
     
    Private Sub creerRelationClientContact(idContact As Long)
        Dim rst As DAO.Recordset
     
        Set rst = CurrentDb.OpenRecordset("clients_contacts")
        rst.AddNew
        rst!id_client = Form_client.id_client.Value
        rst!id_contact = idContact
        rst.Update
    End Sub

    Citation Envoyé par robocop2776
    Dans ce cas est ce que les transactions permettrons de faire les fonctions enregistrerContact et getMaxidContact sans pouvoir être interrompu.
    Théoriquement ça devrait marcher si et seulement si toutes les transactions récupèrent l'identifiant avant que l'un d'elles n'entérine les modifications (Commit).

    Tu vois que dans cette situation l'utilisation d'une transaction n'est pas une garantie suffisante.
    _

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 101
    Points : 64
    Points
    64
    Par défaut
    merci pour ta réponse

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 7
    Dernier message: 20/11/2012, 14h24
  2. Réponses: 2
    Dernier message: 20/01/2012, 10h03
  3. Exporter des données avec les insert
    Par maximenet dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 03/04/2006, 16h20
  4. [MFC] problème avec les insertions dans CComboBox
    Par Joeleclems dans le forum MFC
    Réponses: 12
    Dernier message: 11/06/2004, 15h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo