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

MS SQL Server Discussion :

trigger clé primaire


Sujet :

MS SQL Server

  1. #1
    Membre régulier
    Inscrit en
    Octobre 2007
    Messages
    203
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 203
    Points : 85
    Points
    85
    Par défaut trigger clé primaire
    Bonjours,

    Je suis en face d'un grand mystère!

    J'ai 2 tables :
    - employe(nemp,salemb...)
    - histo_salaire(champs: nemp, datsal,salemb)

    Je dois faire un trigger qui:
    Lorsque je change le salaire d'un employe, j'historise ce salaire dans la table histo_salaire, il doit y avoir au max 10 enregistrement dans table histo sal qui concerne cet employe.

    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
    create trigger histo_10_salaire_v2
    on employe
    for update
    as
    declare @noemp int
     
    declare @date datetime
    declare @sal float
     
    if update(salemb)
    begin
    select @noemp=nemp from Deleted
    select @sal=salemb from Deleted 
     
    while (select count(*)from histo_salaire where nemp=@noemp)>10 --si appliquée à une BD vieille
    	begin
    	select @date=min(datsal) from histo_salaire 	
    	  where nemp=@noemp
    	delete from histo_salaire where datsal=@date and nemp=@noemp
    	end
     
    insert into histo_salaire values(@noemp,getdate(),@sal)
     
    end
    Jusque là tout a l'air de marcher!!
    mais quand j'execute,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    update employe set salemb=40000 where nemp=1
    si cela marche (une fois sur 10), il m'insert 2 fois mon employe dans la table histo_salaire, sinon me marque cette erreur:

    (1 ligne(s) affectée(s))

    Serveur : Msg 2627, Niveau 14, État 1, Procédure histo_10_salaire_v2, Ligne 22
    Violation de la contrainte PRIMARY KEY 'PK__histo_salaire__023D5A04'. Impossible d'insérer une clé en double dans l'objet 'histo_salaire'.
    L'instruction a été arrêtée.


    je ne comprends pas pourquoi il me parle de clé primaire alors que ma table histo_salaire a comme clé nemp et datsal (datetime)!!

    merci d'avance

    claire

  2. #2
    Membre régulier
    Inscrit en
    Octobre 2007
    Messages
    203
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 203
    Points : 85
    Points
    85
    Par défaut
    Après de nombreux test, il me semble que c'est un pb de date.
    En effet ma clé 1aire est nemp et datsal.
    Or l'insertion est refusée casi à chaque fois, dès fois oui je sais pas pourquoi!!!

    pourtant ma datal est de type datetime, donc à chaque fois que je veux faire un insert, l'heure n'est pas la même!!

    si quelqu'un a une idée

    merci encore d'avance

    claire

  3. #3
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    Votre trigger n'est pas ensembliste : que se passera-t-il le jour ou vous mettrez à jour plusieurs salaires ? Hé bien seul le dernier employé affecté par votre mise à jour bénéficiera du traitement de votre trigger, et pas les autres.

    Vous avez écrit un traitement itératif dans votre trigger, qui est lent, alors que vous pouvez écrire votre trigger de façon ensembliste :

    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
    CREATE TRIGGER histo_10_salaire_v2
    	ON employe
    FOR UPDATE
    AS
    BEGIN
    	IF UPDATE(salEmb)
    	BEGIN
    		-- Expression de table commune qui récupère la liset des employés que l'on vient
    		-- de mettre à jour et qui ont plus de 10 lignes dans dbo.histo_salaire
    		WITH
    			CTE_Emp_10_Histo AS
    			(
    				SELECT nEmp,
    					MIN(datSal) minDatSal,
    					COUNT(*) nb
    				FROM dbo.histo_salaire H
    				JOIN DELETED D ON D.nemp = H.nemp
    				GROUP BY nemp
    				HAVING COUNT(*) > 10
    			)
    		-- Suppression des employés trouvés
    		-- dans l'expression de table commune
    		DELETE FROM dbo.Histo_Salaire
    		FROM dbo.Histo_Salaire H
    		JOIN CTE_Emp_10_Histo CTE
    			ON H.nEmp = CTE.nEmp
    			AND H.datSal = CTE.minDatSal
     
    		-- Ajout de l'historique pour tous les employés
    		-- dont le salaire vient d'être mis à jour
    		INSERT INTO dbo.Histo_Salaire
    		(
    			nEmp,
    			datSal,
    			salEmb
    		)
    		SELECT D.nEmp,
    			GETDATE(),
    			D.sal
    	END
    END
    @++

Discussions similaires

  1. Réponses: 11
    Dernier message: 19/07/2010, 23h48
  2. Trigger sysdate et clé primaire
    Par babylone7 dans le forum PL/SQL
    Réponses: 13
    Dernier message: 28/01/2009, 11h11
  3. Lister clés primaires, etrangères et triggers d'un base
    Par Oliveuh dans le forum Requêtes
    Réponses: 1
    Dernier message: 26/05/2008, 23h26
  4. Clefs primaires assignées par trigger
    Par Costalfy dans le forum Hibernate
    Réponses: 8
    Dernier message: 10/08/2007, 11h59
  5. trigger pour tester une clé primaire
    Par keumlebarbare dans le forum PL/SQL
    Réponses: 3
    Dernier message: 15/04/2007, 10h29

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