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

VB.NET Discussion :

insertion sous access avec clé primaire génèré


Sujet :

VB.NET

  1. #1
    Membre averti
    Avatar de alex61
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2010
    Messages
    378
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2010
    Messages : 378
    Points : 392
    Points
    392
    Par défaut insertion sous access avec clé primaire génèré
    bonjour

    j'ai créé une procédure qui devrait insérer des donné dans une table spécifié avec une clé primaire généré : nombre de ligne +1

    la voici :
    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
        Public Sub insererBDD_EPI(ByVal NomEntreprise As String, ByVal type As String, ByVal norme As String, ByVal marque As String, ByVal modele As String, ByVal NumMarquage As String, ByVal annee As String, ByVal dureedevie As String, ByVal resultat As String, ByVal observation As String)
            ' connexion
            Dim cn As New OleDbConnection
            cn = connexionBDD()
            ' generer le code 
            Dim cmdcount As New OleDbCommand
            cmdcount.CommandText = " select count(epi_code) from epi where ent_nom ='" & NomEntreprise & "'"
            cmdcount.Connection = cn
            cmdcount.Connection.Open()
            Dim nb As Integer
            nb = cmdcount.ExecuteNonQuery
            cmdcount.Connection.Close()
            Dim code As String = nb + 1
     
            'insertion 
     
            Dim cmd As New OleDbCommand
            cmd.CommandText = " Insert into EPI (ent_nom,epi_code,epi_type,epi_norme,epi_marque,epi_modele,epi_NumMarquage,epi_AnneeMarquage,epi_dureedevie,epi_resultat,epi_obsevation) values (' " & NomEntreprise & "','" & code & "','" & type & "','" & norme & "','" & marque & "','" & modele & "','" & NumMarquage & "','" & annee & "','" & dureedevie & "','" & resultat & "','" & observation & "')"
            cmd.Connection = cn
            cmd.Connection.Open()
            cmd.ExecuteNonQuery()
            cmd.Connection.Close()
     
        End Sub
    mais ca m'affiche :
    Modifications non effectuées: risque de doublons dans champs index, clé principale ou relation interdisant les doublons. Modifiez les données des champs contenant les doublons, enlevez ou redéfinissez l'index pour permettre les doublons et recommencez.
    dans mon idée visual studio 2005 n'aime pas que je génère la clé primaire comme ca
    il n'existerai pas un moyen de désactivé l'exception
    un truc du genre exception.close ( ca serait trop bien )

    cordialement

  2. #2
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 048
    Points : 2 201
    Points
    2 201
    Par défaut
    Il y a 2 trucs qui sont pas au top dans ton truc.

    1: Si l'on efface un enregistrement, il y a effectivement un risque de doublon. Sauf si on efface toujours depuis l'enregistrement avec le compteur le plus grand (Grosse contrainte à la con...)

    2: Il n'y a pas de transaction, lock, sur ta table ce qui signifie que 2 personnes peuvent enregistrer avec le même identifiant en même temps.

    Utilise une transaction avec le lock qui va bien pour encapsuler les 2 requêtes.
    Utilise un select max(clef)+1 au lieu d'un count, ceci simule un champ compteur sous access en fait (pas tout à fait mais presque).

    Le principal interet pour faire ceci c'est de retrouver la ligne et son identifiant dans le dataset sans se prendre la tête.

    Au final ton erreur est une exception lancée par le moteur de la base de donnée donc le seul moyen de ne pas la voir et d'enlever la contrainte sur la base...

  3. #3
    Membre averti
    Avatar de alex61
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2010
    Messages
    378
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2010
    Messages : 378
    Points : 392
    Points
    392
    Par défaut
    oué j'avais pas penser a la suppression vu que normalement personne ne doit supprimer de chose de cette base ( mais vaut mieux prévoir c'est vrai )

    je test le max(primarykey)

  4. #4
    Membre averti
    Avatar de alex61
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2010
    Messages
    378
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2010
    Messages : 378
    Points : 392
    Points
    392
    Par défaut
    je n'arrive pas a récupérer le résultat du select

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
            Dim cmdcount As New OleDbCommand
            cmdcount.CommandText = " select max(epi_code) from epi where ent_nom ='" & NomEntreprise & "'"
            cmdcount.Connection = cn
            cmdcount.Connection.Open()
            Dim nb As String
            nb = cmdcount.ExecuteNonQuery
            Dim reader As OleDbDataReader = cmdcount.ExecuteReader()
            nb = reader(0).ToString()
            reader.Close()
            cmdcount.Connection.Close()
            Dim code As String = nb + 1
    ca me met
    Aucune donnée n'existe pour la ligne/colonne.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Février 2010
    Messages
    291
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 291
    Points : 390
    Points
    390
    Par défaut
    Bonjour,

    Utiliser une fonction Max() avec un type string .... hum
    Générer une clef primaire sur un type String pas bonne pratique.

    Petite remarque pour la lisibilité il est tout de même mieux de mettre les commande SQL en majuscule.

  6. #6
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 048
    Points : 2 201
    Points
    2 201
    Par défaut
    Ouh bien vu le coup de la String...

    En effet Max va fonctionner que sur des nombres.

    Vu que ta colonne est un string tu peux passer par la génération d'un GUID aussi (c'est même mieux selon l'avis de certains) Ou alors tu transforme la colonne en numérique (Entier, pas à virgule!).

    Sur les GUID

    http://msdn.microsoft.com/en-us/libr...d.newguid.aspx

    En gros c'est une fonction qui te génère une chaîne unique (c'est à dire que en théorie la fonction ne renvoie jamais 2 fois le résultat (enfin si mais avec une probablité très très faible, même sur des machines différentes). Parfait pour un identifiant!

    Met quand même un test pour gérer le cas ou il y a un doublon (même si t'as plus de chance de gagner quelque fois à l'euromillion avant que ça arrive...)

    P.S. Pour les requêtes qui envoie 1 colonne et 1 Ligne (Une valeur en résumé) on peut utiliser le .ExecuteScalar à la place d'un datareader.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Février 2010
    Messages
    291
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 291
    Points : 390
    Points
    390
    Par défaut
    Bonjour,

    De rien pour la String c'est pas tendu

    Utiliser GUID pourquoi pas mais bon en utilisant ACCESS la bonne pratique c'est d'utiliser un champs numéroauto pour la clef primaire et si l'on souhaite avoir un champs string avec une valeur unique ajouter cette contrainte d'unicité sur ce champs. Dans ce cadre la requête INSERT INTO ne devra pas comporter le champs de clef primaire.

  8. #8
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 442
    Points
    4 442
    Par défaut index ,insert into
    bonjour
    tu est sur que cette instruction fantoche est bonne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Dim code As String = nb + 1
    'au lieu de :
    Dim code As String =( nb + 1).ToString
    et que d'autres tables liees en cascade a cette table comporte un index base sur l'un des champs autre que code.
    Le moteur Jet est intraitable.
    bon code.............

  9. #9
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 048
    Points : 2 201
    Points
    2 201
    Par défaut
    Utiliser GUID pourquoi pas mais bon en utilisant ACCESS la bonne pratique c'est d'utiliser un champs numéroauto pour la clef primaire et si l'on souhaite avoir un champs string avec une valeur unique ajouter cette contrainte d'unicité sur ce champs. Dans ce cadre la requête INSERT INTO ne devra pas comporter le champs de clef primaire.
    Le soucis c'est que si l'on veux récupérer l'enregistrement après son insertion, pour l'inclure dans une datatable en local, ou pour enregistrer des champs filles ensuite, il est nécessaire d'avoir la valeur de cette clé. Il existe certes des méthodes avec la fonction Merge() permettant de résoudre ce problèmes mais c'est pas tout simple. Du coup générer le champ incrément auto "à la main" avant l'insertion permet de résoudre ce problème.

    Mais bon un chiffre auto incrémenter (auto ou a la main) doit être numérique et non pas une chaîne de caractère.

    Le GUID prend tout son sens s'il y a un synchro avec plusieurs base de donnée (appareil mobile, plusieurs site qui se synchronise avec la maison mère, etc) on évite ainsi de devoir traiter les doublons ("garanti" l'unicité dans le temps et l'espace).

    J'ignore l'impact niveau performance par contre.

  10. #10
    Membre averti
    Avatar de alex61
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2010
    Messages
    378
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2010
    Messages : 378
    Points : 392
    Points
    392
    Par défaut
    vous connaissait vraiment pas quelque chose pour désactive les message d'erreur sous access parce que j'ai deja utiliser une base de donné sql serveur et il n'y avait pas autant de message d'erreur

    par exemple je vien de créé un procédure pour insérer un occurrence dans une table , elle ne marche pas , d accord mais pourquoi ? , j'en ai fait deux autre avec le même code qui fonctionne très bien ...

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Février 2010
    Messages
    291
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 291
    Points : 390
    Points
    390
    Par défaut
    Bonjour,

    Utiliser ACCESS pour synchroniser plusieurs bases, ou sur différents sites ... je choisirai pas forcement ce type de BD.
    Autrement pour les tables liées il y a la possibilité que tuévoquais du MAX(ID_nomtable) pour récupérer la dernière clef primaire générée quand elle est autoincrémentée par le moteur jet. Avec le risque d'accès multiples (est-ce que c'est moi qui ait générer la dernière clef ?). Pour ma part je préfère faire une requête avec des clauses WHERE qui me garantissent que je récupère bien l'enregistrement que je viens de créer, et donc la clef primaire.
    NB c'était tout de même plus simple avec DAO car là on récupérait directement la clef primaire après l'update.

  12. #12
    Membre averti
    Avatar de alex61
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mai 2010
    Messages
    378
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Canada

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mai 2010
    Messages : 378
    Points : 392
    Points
    392
    Par défaut
    personnellement access serait surement le dernier sgbd que j'utiliserai , enfin si on peu appelé ca un sgbd ^^

    mais c'est une contrainte de mon projet car je doit optimiser l'automatisation des enregistrement dans ce service et donc ils ont déjà un existant

    mais laisser tomber j'ai trouver une bidouille pour éviter de générer des clé primaire séquentiel


    cordialement

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

Discussions similaires

  1. [AC-2003] Fonction DiffDate sous Access(avec paramètre)
    Par Dodo86 dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 28/09/2009, 15h53
  2. [SQL]Problème requete sql sous access avec vba
    Par aaliyan dans le forum Requêtes et SQL.
    Réponses: 8
    Dernier message: 13/04/2007, 18h53
  3. Insertion sous Access avec Compos ADO
    Par Andry dans le forum Bases de données
    Réponses: 14
    Dernier message: 10/11/2006, 09h22
  4. Requete sous Access avec AND et OR
    Par paflolo dans le forum Langage SQL
    Réponses: 2
    Dernier message: 28/02/2006, 10h35
  5. Réponses: 8
    Dernier message: 20/02/2006, 23h25

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