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

Accès aux données Discussion :

Champ "auto increment"


Sujet :

Accès aux données

  1. #1
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 33
    Par défaut Champ "auto increment"
    Slt à tous,

    Quelqu'un saurait-il comment on récupère un champ "auto-increment" lors d'une requete d'insertion dans une table via ADO.NET?

    Merci d'avance.

  2. #2
    Expert confirmé
    Avatar de bidou
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2002
    Messages
    3 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 055
    Par défaut
    avec une requête qui va dépendre du SGBD

  3. #3
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 33
    Par défaut
    Elle est où la portabilité sous ADO.NET s'il faut modifier le code pour une fonctionnalité au moins aussi basique que fréquemment utilisée?

    Est ce que je pourrais avoir un exemple sous un SGBDR de ton choix (de préférence Access,SQl Server ou MySQL qui sont installés sur ma machine)?


    Merci pour ta réponse

  4. #4
    Rédacteur
    Avatar de The_badger_man
    Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    2 745
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 745
    Par défaut
    Si tu veux de la portabilité, tu ne fais pas ta requete dans le code. Tu fais une procédure stockée qui te renvoie l'identifiant.

    Sinon la récupération dépend de ton SGBD.

    Sous SQL Server il fait utiliser la fonction SCOPE_IDENTITY( ) : ( SELECT SCOPE_IDENTITY() ).

    Sous Oracle les champs auto incrémenté n'existent pas (je dis pas de connerie là ? ) c'est remplacé par des séquences.
    Les règles du forum
    Le trio magique : FAQ + Cours + fonction rechercher
    Mes articles
    Pas de questions par messages privés svp

    Software is never finished, only abandoned.

  5. #5
    Expert confirmé
    Avatar de bidou
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2002
    Messages
    3 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 055
    Par défaut
    Franchement elle est bonne celle là. Comme si c'était la faute d'ADO.NET si le jeu préféré des éditeurs de SGBD est d'implémenter chacun des langages à la con plutôt que de suivre les normes SQL...

  6. #6
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 33
    Par défaut
    Sous Oracle les champs auto incrémenté n'existent pas (je dis pas de connerie là ? ) c'est remplacé par des séquences.
    On peut simuler les auto increments sous Oracle avec une séquence associé à un TRIGGER.

    Franchement elle est bonne celle là. Comme si c'était la faute d'ADO.NET si le jeu préféré des éditeurs de SGBD est d'implémenter chacun des langages à la con plutôt que de suivre les normes SQL...
    Je pense pouvoir avancé avec peu de risque de me tromper que pratiquement tous les SGBDR (corrige moi si je me trompe) dispose de cette fonctionnalité sous des noms ou sous des formes différentes. ce qui fait qu'en Java, sous JDBC, il existe une fonctionnalité standard permettant de récupérer ce type de champ (il s'agit de la méthode getGeneratedKeys() de l'interface Statement)! Libre au Driver utilisé de récupérer la bonne valeur.

    Et on ne peu pas dire que .NET, comparé à JAVA, soit un modèle de portabilité!

  7. #7
    Expert confirmé
    Avatar de bidou
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2002
    Messages
    3 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 055
    Par défaut
    oui, l'ancienne version d'ADO en avait une aussi, qui posait plus de problème qu'elle n'en résolvait d'ailleurs ce qui est aussi le cas de getGeneratedKeys.
    Quelle est l'intérêt d'utiliser une méthode qui renverra potentiellement n'importe quoi si le fournisseur ne la gère pas ???
    La programmation 'générique' des SGBD restera toujours une légende tant que la norme SQL ne sera pas strictement respectée par la plupart des SGBD.

  8. #8
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 33
    Par défaut
    Je pense que la plupart des SGBDR respectent la norme (je dis bien la plupart parce que ce n'était pas le cas de MySQL par exemple pendant un bon moment), mais rejoutent à celle-ci des fonctionnalités pour rendre leur produit plus séduisant! Libre à nous de limiter notre utilisation de SQL trictement à la norme ANSI.

    Il demeure vrai que s'ils se limitaient tous trictement à SQL ANSI, la vie serait plus facile pour tous, mais c'est la une vision pour le peu utopique!

    En ce qui concerne getGeneratedKeys(), il est vrai que certains pilotent JAVA ne l'implémentent pas (par exemple le pilote ODBC si ma mémoire est bonne), mais ceux qui l'implémentent ne renvoient pas "n'importe quoi" comme tu dis.

    Quoi qu'il en soit, je pense que ce type de fonctionnalité est indispensable dans une bonne conception et je trouve dommage que ce ne soit pas un standard SQL.

  9. #9
    Expert confirmé
    Avatar de bidou
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2002
    Messages
    3 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 055
    Par défaut
    Reste à savoir de quelle norme on parle, car la plupart respecte SQL2 mais pas les versions suivantes, ce qui est une approche quand même un peu minimaliste.

    Si ADO.NET n'implémente pas de méthode générique de récupération de clé alors que ADO le faisait, c'est bien parce que potentiellement cela renvoie une valeur erronée. Dans le principe couramment admis, c'est la procédure SGBD qui doit renvoyée la clé et non une requête postèrieure à la procédure d'insertion. Car dans un contexte multi utilisateurs, il existe rarement la garantie qu'il n'y aura pas eu un autre enregistrement ajouté et donc une erreur dans la clé récupérée. A mon sens, les méthodes comme getGeneratedKeys ou UpDateResync sont des faux amis car il masque le code SQL de récupération effectivement envoyé et donc les erreurs potentielles que celui ci peut contenir ou engendrer.

  10. #10
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 33
    Par défaut
    Si nous sommes bien d'accord avec le fait qu'un champ incrémenté comme identifiant d'une table est une bonne conception, comment me conseillerais tu donc d'implémenter cette fonctionnalité tout en restant indépendant du SGBDR?

  11. #11
    Expert confirmé
    Avatar de bidou
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2002
    Messages
    3 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 055
    Par défaut
    Recharger partiellement les tables, c'est à ma connaissance le seul moyen universel de récupérer les bonnes valeurs à coup sur

  12. #12
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 33
    Par défaut
    Recharger partiellement les tables, c'est à ma connaissance le seul moyen universel de récupérer les bonnes valeurs à coup sur
    ç'est à dire? Qu'est ce tu entends par "recharger partiellement les tables"?

  13. #13
    Expert confirmé
    Avatar de bidou
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2002
    Messages
    3 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 055
    Par défaut
    J'entends faire un Fill de toutes les tables ayant eu des Insert au moins à partir du dernier numéro de clé originale en désactivant les contraintes.

    Fondamentalement, le problème des clé auto générés dans une application est double, il n'est pas évident de récupérer le bon numéro de clé et les enregistrements liés doivent mettre à jour la clé étrangère correctement aussi, sauf si on fait une mise à jour partielle entre la création du parent et celle des enfants.
    Pour contourner ce problèmes, on donne au niveau du Dataset des clés négatives pour être sur de ne pas avoir de collision, en désactive EnforceConstraint, on envoie la ou les mise(s) à jour, on recharge la ou les table(s), on effectue un rejectChanges sur les lignes ajoutées pour supprimer les enregistrements à clé négative et on rétablit EnforceConstraint.
    Si les tables sont petites, pas de problèmes pour recharger toute la table, mais si tu as des dizaines de milliers d'enregistrement, c'est vite l'usine à gaz. Dans ce cas, on recharge la table en utilisant une requète avec un prédicat restrictif sur la clé.
    Par exemple supposons que lors du premier chargement (donc avant les modifs) ta table contenait les enregistrement jusqu'à la clé 152321, on refait un Fill avec une requête du genre Select * From Table Where Id>152300

    Je sais c'est un peu lourd, mais c'est la seule méthode universelle fiable

  14. #14
    Rédacteur
    Avatar de The_badger_man
    Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    2 745
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 745
    Par défaut
    oui mais s'il n'utilise pas de dataset ?
    Les règles du forum
    Le trio magique : FAQ + Cours + fonction rechercher
    Mes articles
    Pas de questions par messages privés svp

    Software is never finished, only abandoned.

  15. #15
    Expert confirmé
    Avatar de bidou
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mai 2002
    Messages
    3 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 055
    Par défaut
    la démarche reste la même, l'objet de stockage est sans importance

  16. #16
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 33
    Par défaut
    Je sais c'est un peu lourd, mais c'est la seule méthode universelle fiable
    C'est le cas de le dire. J'utiliserais très bientot .NET dans un domaine ou la séparation en 3 couches est primordiale et ou la gestion de la concurrence d'accès doit être optimale. dans ces conditions la, je ne pense pas que les DataSet soient la solution à adopter. Compte tenu du fait que je vais utilisé plutot ADO.NET en mode connecté, que pensez vous de faire dans une même transaction ou dans un batch de requêtes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT MAX(ID)+1 FROM MyTABLE
    initialiser l'id à 1 si on a aucun résultat, et puis faire notre requete d'insertion?

Discussions similaires

  1. Réponses: 10
    Dernier message: 21/05/2015, 19h58
  2. Champ auto increment
    Par webbulls dans le forum Bases de données
    Réponses: 9
    Dernier message: 21/04/2004, 17h07
  3. Remise à zero champ auto-incrementé (SQL Server)
    Par James85 dans le forum Langage SQL
    Réponses: 6
    Dernier message: 26/01/2004, 10h23
  4. Nom du champs auto-incrementé
    Par norroy dans le forum Requêtes
    Réponses: 2
    Dernier message: 17/06/2003, 19h30

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