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

Langage SQL Discussion :

Trigger pour incrémentation de champs


Sujet :

Langage SQL

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Student
    Inscrit en
    Septembre 2014
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Student

    Informations forums :
    Inscription : Septembre 2014
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Trigger pour incrémentation de champs
    Bonjour à tous,

    Je voudrais créer un trigger qui incrémente un champ (id_groupe) dans ma base de données après une insertion car suite à une erreur dans la conception de celle-ci , elle n'est pas en auto-incrément et il m'est impossible de le rajouter étant donné qu'elle contient des enregistrements est qu'elle est relié à plusieurs table

    pouvez-vous me donner quelque piste car niveau trigger je suis pas très au point.

    merci d'avance

  2. #2
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2010
    Messages : 4 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Les champs sont à la campagne et les colonnes dans les tables
    Sinon, le plus simple est de passer par une table compteur, sous réserve d'avoir des performances très pourries (si vous faites un MAX à chaque fois).

    Basez-vous sur ce trigger.
    http://www.developpez.net/forums/d14...f/#post7948369

    PS : Attention, il faut bien penser trigger "statement" et non "row". On peut parfaitement insérer un lot de ligne en une seule requête.
    On ne jouit bien que de ce qu’on partage.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Student
    Inscrit en
    Septembre 2014
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Student

    Informations forums :
    Inscription : Septembre 2014
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Merci pour la réponse Sylvain j'étais déjà tomber sur le post que vous m'avez fournis lors de ma recherche avant mon poste mais je ne savais pas que cela aurait pu être la soluce .. !

    sinon qu'entendez vous par perte de performances ? à partir de combien d'enregistrement cela peut induire sur les performance de la base ?.

  4. #4
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2010
    Messages : 4 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Rechercher le MAX() sur une colonne peut rapidement prendre du temps, même si c'est la PK clustered.

    Après, s'il y a "quelques lignes" (on va dire moins de 10000) évidement, c'est pour ainsi dire instantané. Mais quand on arrive au million, les performances peuvent rapidement diminuer.

    Dans tous les cas, passer par une table compteur (ou une séquence, mais c'est dispo qu'à partir de SQL Server 2012) permet de conserver des performances linéaires quelle que soit la taille de la table.
    On ne jouit bien que de ce qu’on partage.

  5. #5
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Sur MySQL, on peut ajouter l'auto-incrémentation après coup.

    Je viens de tester avec quelques lignes dont le plus gros identifiant était 56 mais pas sur la dernière ligne insérée et MySQL a commencé tout seul l'auto-incrémentation à 57 sans toucher aux id existants.

    Je ne sais pas si les autres SGBD font pareil.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  6. #6
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2010
    Messages : 4 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    MySQL est le seul à ma connaissance à fonctionner de la sorte.

    C'est aussi le seul à boucher automatiquement les trous dans une colonne auto-incrément, ou à gérer plusieurs compteur pour une même table en cas de clé composite.


    Sous Oracle, si je ne m'abuse, ça n'existe tout bonnement pas (on doit se taper les auto-incrément à la main à l'aide de triggers et de séquences).

    Et sous SQL Server, "identity" est bien plus limité en termes de fonctionnalités.

    Exemple avec SQL Server :
    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
     
    drop table autonum;
    go
     
    create table autonum
    (
    	id int primary key,
    	nom varchar(10) not null
    );
    go
     
    insert into autonum (id, nom) values (1, 'toto');
    insert into autonum (id, nom) values (2, 'titi');
    insert into autonum (id, nom) values (4, 'tutu');
    go
     
    alter table dbo.autonum alter column id int identity;
    go
     
    insert into autonum (nom) values ('tata');
    go

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    (1*ligne(s) affectée(s))
     
    (1*ligne(s) affectée(s))
     
    (1*ligne(s) affectée(s))
    Msg*156, Niveau*15, État*1, Ligne*16
    Syntaxe incorrecte vers le mot clé 'identity'.
    Msg*515, Niveau*16, État*2, Ligne*19
    Impossible d'insérer la valeur NULL dans la colonne 'id', table 'tempdb.dbo.autonum'. Cette colonne n'accepte pas les valeurs NULL. Échec de INSERT.
    L'instruction a été arrêtée.
    Il a pas voulu ajouter identity à ma colonne.

    Maintenant, il existe divers moyens pour pallier au problème avec SQL Server :

    Voici un exemple complet en recréant la table :
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    drop table autonum;
    go
     
    create table autonum
    (
    	id int primary key,
    	nom varchar(10) not null
    );
    go
     
    insert into autonum (id, nom) values (1, 'toto');
    insert into autonum (id, nom) values (2, 'titi');
    insert into autonum (id, nom) values (4, 'tutu');
    go
     
    sp_RENAME 'autonum' , 'old_autonum';
    go
     
    create table autonum
    (
    	id int primary key identity,
    	nom varchar(10) not null
    );
    go
     
    set IDENTITY_INSERT autonum on;
    insert into autonum (id, nom)
    select id, nom from old_autonum;
    set IDENTITY_INSERT autonum off;
    go
     
    drop table old_autonum;
    go
     
    insert into autonum (nom) values ('tata');
    go
     
    select * from autonum;

    Evidement, s'il y a des données liées, ça va pas être pratique.

    La solution consistant à créer une colonne identity avant de supprimer l'ancienne est pas mal aussi, au détail près qu'on ne peu pas initialiser les lignes avec l'ancienne valeur, et du coup s'il y a des tables qui font référence à cette table, marche pas non plus...
    On ne jouit bien que de ce qu’on partage.

  7. #7
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2010
    Messages : 4 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Voici la même chose, mais avec un trigger + table compteur.

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
     
    create table autonum
    (
    	id int primary key,
    	nom varchar(10) not null
    );
    go
     
    insert into autonum (id, nom) values (1, 'toto');
    insert into autonum (id, nom) values (2, 'titi');
    insert into autonum (id, nom) values (4, 'tutu');
    go
     
    create table compteur
    (
    	id int identity primary key,
    	nom varchar(10) not null unique,
    	valeur int not null default 0
    );
    go
     
    insert into compteur (nom, valeur)
    select 'autonum', max(id)
    from autonum;
    go
     
    create trigger trg_autonum_compteur
    on autonum
    instead of insert
    as
    begin
    	insert into autonum (id, nom)
    	select c.valeur + ROW_NUMBER() over (order by i.id), i.nom
    	from compteur c with (xlock rowlock)
    	cross join inserted i
    	where c.nom = 'autonum';
     
    	update compteur
    	set valeur = valeur + (select count(*) from inserted)
    	where nom = 'autonum';
    end;
    go
     
    insert into autonum (nom) values ('tata');
    insert into autonum (nom)
    select 'tyty'
    union all
    select 'tztz'
    union all
    select 'trtr';
    go
     
    select * from autonum;
    select * from compteur;
     
    drop table autonum;
    drop table compteur;
    go
    On ne jouit bien que de ce qu’on partage.

  8. #8
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2014
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2014
    Messages : 37
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    Sous Oracle, si je ne m'abuse, ça n'existe tout bonnement pas (on doit se taper les auto-incrément à la main à l'aide de triggers et de séquences).
    Bonjour,

    vous vous abusez

    Il existe un "auto increment" sur Oracle depuis la version 12c si je ne m'abuse avec l'utilisation du mot clé identity. (plus d'info sur l'utilisation ici).
    Pour les messages utiles, mettre un pouce vert fait plaisir à celui qui donne de son temps pour aider. (en tout cas, ça me fait plaisir)

  9. #9
    Modérateur
    Avatar de Chtulus
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2008
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Santé

    Informations forums :
    Inscription : Avril 2008
    Messages : 3 094
    Points : 8 678
    Points
    8 678
    Par défaut
    Bonjour StringBuilder,

    Citation Envoyé par StringBuilder Voir le message
    MySQL est le seul à ma connaissance à fonctionner de la sorte.

    C'est aussi le seul à boucher automatiquement les trous dans une colonne auto-incrément
    Hummm, ça c'est une très mauvaise idée pour moi.

    Dans une bonne conception on ne bouche pas les trous !

    « Je ne cherche pas à connaître les réponses, je cherche à comprendre les questions. »
    - Confucius -

    Les meilleurs cours, tutoriels et Docs sur les SGBD et le SQL
    Tous les cours Office
    Solutions d'Entreprise



  10. #10
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par Chtulus Voir le message
    Dans une bonne conception on ne bouche pas les trous !
    Oui, surtout avec MySQL qui ne pousse pas vraiment à déclarer les contrainte d'intégrité.
    C'est un coup a se retrouver avec un client qui - à peine enregistré - se retrouve avec plein de factures a payer car il a "bouché le trou" d'un ancien client ayant laissé une ardoise ...

  11. #11
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Février 2010
    Messages : 4 153
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par A.Herobic Voir le message
    Vous vous abusez
    Boarf

    Bon, je saurai pour la prochaine fois.

    M'enfin c'est pas si vieux que ça du coup
    On ne jouit bien que de ce qu’on partage.

Discussions similaires

  1. Trigger sur un INSERT pour incrémenter un champ
    Par leilan dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 23/07/2014, 09h59
  2. [AC-2010] expression pour incrémenter un champ
    Par sebinator dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 08/10/2012, 12h19
  3. Trigger qui incrémente un champ
    Par Almenor dans le forum PL/SQL
    Réponses: 20
    Dernier message: 06/03/2012, 13h08
  4. [Billet Blog] Trigger pour incrémentation relative
    Par CinePhil dans le forum SQL Procédural
    Réponses: 0
    Dernier message: 08/09/2011, 14h30
  5. Trigger Pour Afficher Le Champ D'une Table
    Par y.legouadec dans le forum Développement
    Réponses: 5
    Dernier message: 05/10/2006, 22h40

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