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

Bases de données Delphi Discussion :

Réinitialisation d'un champ auto incrément


Sujet :

Bases de données Delphi

  1. #1
    Nouveau Candidat au Club
    Femme Profil pro
    ingénieur d'état en informatique
    Inscrit en
    Août 2013
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Algérie

    Informations professionnelles :
    Activité : ingénieur d'état en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Août 2013
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Réinitialisation d'un champ auto incrément
    Bonjour Je suis entraine de réaliser une application sous delphi et j'ai rencontré un problème qui est le suivant: à chaque fois que j'ajoute un enregistrement je dois incrémenter un champ comme suit: numéro auto incrément slash année en cours exemple: 11/2014 chose qui est faite mais à chaque fois que l'année change je veux que le numéro se réinitialise à 1 puis s'incrémente à chaque ajout d'un enregistrement.
    le code est:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TForm1.Button1Click(Sender: TObject); 
    begin 
    ADOTable1.FieldByName('numero').Value:=inttostr(ADOTable1.RecordCount+1)+'/'+FormatDatetime('YYYY',now); 
    end;
    S'il vous plait aidez-moi si quelqu'un a une idée
    Merci
    PS: la BDD utilisée est mysql

  2. #2
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 784
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 784
    Points : 5 915
    Points
    5 915
    Par défaut
    Bonjour,
    Citation Envoyé par iris84 Voir le message
    Bonjour Je suis entraine de réaliser une application sous delphi et j'ai rencontré un problème qui est le suivant: à chaque fois que j'ajoute un enregistrement je dois incrémenter un champ comme suit: numéro auto incrément slash année en cours exemple: 11/2014 chose qui est faite mais à chaque fois que l'année change je veux que le numéro se réinitialise à 1 puis s'incrémente à chaque ajout d'un enregistrement.
    le code est:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TForm1.Button1Click(Sender: TObject); 
    begin 
    ADOTable1.FieldByName('numero').Value:=inttostr(ADOTable1.RecordCount+1)+'/'+FormatDatetime('YYYY',now); 
    end;
    Gérer l'incrémentation à chaque ajout d'un enregistrement en se basant sur la valeur de RecordCount est extrèmement dangeureux et à proscrire.
    En voici 2 raisons parmi d'autres :
    1. 2 utilisateurs saisissent simultanément un enregistrement. Les 2 enregistrements auront la même valeur !
    2. J'ai 10 enregistrements dans la table, je supprime un des 9 premiers, j'en saisis un nouveau. Le 10° enregistrement et le dernier saisi auront la même valeur !

    Citation Envoyé par iris84 Voir le message
    S'il vous plait aidez-moi si quelqu'un a une idée
    Merci
    PS: la BDD utilisée est mysql
    Voici une solution parmi d'autres :
    1. Créer une table T_AN_INC(ANNEE INTEGER, INCREMENT INTEGER) qui contiendra pour chaque année visée la dernière valeur d'incrément utilisée. ANNEE étant la clé primaire...
      Exemple de contenu:
      2011, 1234
      2012, 1325
      2013, 1367
      2014, 781
    2. Créer une procédure stockée chargée de fournir la prochaine valeur d'incrément pour une année donnée. Cette procédure devra être dotée d'une transaction, compléter la table pour une nouvelle année.
      Voici un squelette de procédure, à tester et amender si nécessaire (rajouter des contrôles de borne sur le paramètre YEAR)...
      Code sql : 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
      CREATE PROCEDURE SP_GET_INC_BY_YEAR(IN YEAR INT, OUT NEW_INC INT)
      BEGIN
        -- nécessaire pour gérer correctement la transaction et son atomicité
        DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
        DECLARE EXIT HANDLER FOR SQLWARNING ROLLBACK;
       
        -- Débit de transaction
        START TRANSACTION;
       
        -- Lire la valeur actuelle de l'année visée
        SELECT INCREMENT INTO NEW_INC FROM T_AN_INC WHERE ANNEE = YEAR;  
       
        -- Si l'année demandée n'existe pas dans la table
        IF NEW_INC IS NULL THEN
          -- insérer dans la table une ligne pour l'année visée avec une valeur intiale = 0
          SET NEW_INC = 0;
          INSERT INTO T_AN_INC VALUES(YEAR, NEW_INC);
        END IF;
       
        -- Incrémenter de 1 la valeur
        SET NEW_INC = NEW_INC + 1;
       
        -- Mettre à jour la table avec cette valeur incrémentée
        UPDATE T_AN_INC 
        SET INCREMENT = NEW_INC
        WHERE ANNEE = YEAR;
       
        COMMIT;
      END
    3. Lors de l'enregistrement d'une ligne dans votre table, on appelle cette procédure (attention à gérer les éventuelles exceptions) qui nous retourne l'incrément à utiliser, on complète la ligne et on la sauve...
    Philippe.

  3. #3
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 385
    Points : 2 999
    Points
    2 999
    Par défaut
    D'accord avec Ph. B. !

    Mais je rajouterai que ce genre de chose devrait se faire dans un Trigger au niveau de la base.

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 037
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    Je plussoie, cependant

    Citation Envoyé par Papy214 Voir le message
    Mais je rajouterai que ce genre de chose devrait se faire dans un Trigger au niveau de la base.
    Mais avec MySQL
    Citation Envoyé par doc mysql
    Le support des déclencheurs (aussi appelés trigger ) a commencé avec MySQL 5.0.2. Actuellement, le support des déclencheurs est rudimentaire
    en fait si je compare a Firebird c'est même plus que rudimentaire et ne correspondrai pas à la demande , la solution de Philippe me semble donc la seule applicable a mySQL
    peut être qu'un tour dans le forum mySQL fournira d'autres réponses
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  5. #5
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 385
    Points : 2 999
    Points
    2 999
    Par défaut
    et la version 5.0.2 est sorti il y a combien de temps ?
    Sans être spécialiste MySQL, est-ce qu'il n'est raisonnable d'utiliser les versions récentes ?

    D'ailleurs, la question ne précise pas la version utilisée

  6. #6
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 037
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Citation Envoyé par Papy214 Voir le message
    et la version 5.0.2 est sorti il y a combien de temps ?
    Sans être spécialiste MySQL, est-ce qu'il n'est raisonnable d'utiliser les versions récentes ?
    d'après wiki la dernière version serait la 5.6 sortie fin 2013 , maintenant je ne connais pas vraiment ce SGBD malgré sa popularité
    Citation Envoyé par Papy214
    D'ailleurs, la question ne précise pas la version utilisée
    lire le PS du post
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  7. #7
    Candidat au Club
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2015
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 35
    Localisation : Algérie

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

    Informations forums :
    Inscription : Janvier 2015
    Messages : 1
    Points : 2
    Points
    2
    Par défaut réinitialisation d'un champ auto incrément sous delphi
    Bonjour;
    J'ai le même problème que iris84 mais J'ai pas bien compris votre solution
    (Je ne maitrise pas beaucoup le delphi et les trigger mysql)
    Merci

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 454
    Points : 24 866
    Points
    24 866
    Par défaut
    en MySQL avec les fichiers MyISAM
    si l'on utilise un champ AUTOINC comme deuxieme colonne d'une clé primaire, la séquence est géré indépendemment pour chaque valeur de la première colonne format la clé primaire composite

    je n'ai pas MySQL sous la main, mais le SQL devrait être

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE TABLE toto
    (
      year INTEGER(4),
      Cpt INTEGER(9) NOT NULL AUTO_INCREMENT,
      PRIMARY KEY (year , cpt)
    ) ENGINE=MyISAM;

    Ensuite, ce que de l'affichage de présenter sous la forme 11/2014

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT Cpt || '/' || year as Affichage FROM toto;

    En fait, c'est même écrit dans l'aide : MySQL 5.0 Reference Manual :: 3 Tutorial :: 3.6 Examples of Common Queries :: 3.6.9 Using AUTO_INCREMENT

    For MyISAM and BDB tables you can specify AUTO_INCREMENT on a secondary column in a multiple-column index. In this case, the generated value for the AUTO_INCREMENT column is calculated as MAX(auto_increment_column) + 1 WHERE prefix=given-prefix. This is useful when you want to put data into ordered groups.
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE TABLE animals (
        grp ENUM('fish','mammal','bird') NOT NULL,
        id MEDIUMINT NOT NULL AUTO_INCREMENT,
        name CHAR(30) NOT NULL,
        PRIMARY KEY (grp,id)
    ) ENGINE=MyISAM;

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    INSERT INTO animals (grp,name) VALUES
        ('mammal','dog'),('mammal','cat'),
        ('bird','penguin'),('fish','lax'),('mammal','whale'),
        ('bird','ostrich');
     
    SELECT * FROM animals ORDER BY grp,id;

    Which returns:
    +--------+----+---------+
    | grp | id | name |
    +--------+----+---------+
    | fish | 1 | lax |
    | mammal | 1 | dog |
    | mammal | 2 | cat |
    | mammal | 3 | whale |
    | bird | 1 | penguin |
    | bird | 2 | ostrich |
    +--------+----+---------+


    In this case (when the AUTO_INCREMENT column is part of a multiple-column index), AUTO_INCREMENT values are reused if you delete the row with the biggest AUTO_INCREMENT value in any group. This happens even for MyISAM tables, for which AUTO_INCREMENT values normally are not reused.

    En InnoDB, ce n'est pas faisable automatiquement
    il faut le faire par trigger, désolé, je n'ai que la syntaxe ORACLE et pas la syntaxe MySQL sous la main
    Code sql : 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
     
    CREATE TABLE toto
    (
      year INTEGER(4)  NOT NULL,
      Cpt INTEGER(9) NOT NULL ,
      PRIMARY KEY (year , cpt)
    ) ENGINE=InnoDB;
    --
    CREATE OR REPLACE TRIGGER TRIG_PK_TOTO BEFORE INSERT ON TOTO
    FOR EACH ROW
    WHEN (NEW.cpt IS NULL)
    BEGIN
      SELECT MAX(cpt) + 1 INTO :NEW.cpt FROM T_SUB_ITEM WHERE year = :NEW.year;
      IF (:NEW.cpt IS NULL) THEN
        :NEW.cpt := 1;
      END IF;
    END;
    --
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

Discussions similaires

  1. [EJB2.1 Entity] [Débutant] Champs auto-incrémenté (identity)et EJB
    Par Houbbba dans le forum Java EE
    Réponses: 9
    Dernier message: 04/04/2006, 19h15
  2. [MSSQL 2000] Réinitialiser un compteur d'auto-incrément
    Par major2 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 26/01/2006, 14h20
  3. champ auto incrémenté
    Par Kerod dans le forum Langage SQL
    Réponses: 6
    Dernier message: 21/09/2005, 17h29
  4. [BCB5][FB 1.5]IBDataSet et champ Auto-incrémenté
    Par Sitting Bull dans le forum Connexion aux bases de données
    Réponses: 4
    Dernier message: 21/07/2004, 15h37
  5. [JDO]Hibernate : Mapping d'un champ auto-incrémenté
    Par brice.antoine dans le forum Hibernate
    Réponses: 4
    Dernier message: 02/04/2004, 10h36

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