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 Insertion instead of


Sujet :

MS SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Ingénieur Junior développement logiciels
    Inscrit en
    Mai 2014
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Junior développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 198
    Par défaut Trigger Insertion instead of
    Bonjour,


    Je suis actuellement en cours de réalisations de trigger (sur SQLServer) mais je trouve que ce que je fait n'est pas top.

    Mon trigger ressemble à ceci :

    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
    42
    43
    44
    45
    46
     
     
    create trigger TI_CommandeFournisseur
    on CommandeFournisseurs
    instead of Insert
    as 
     
    Begin
    Declare @max int
    Declare @prefix varchar(10);
    Declare @inserted_year varchar(2)
    Declare @lastcommande_year varchar(2)
    Declare @res varchar(11)
     
     
    select @max=max(cast((substring(NumeroCommande,6,len(NumeroCommande)-5))as int)) from CommandeFournisseurs;
    select @lastcommande_year=right(Year((select top 1 DateCommande from CommandeFournisseurs order by NumeroCommande desc)),2);
    select @inserted_year=right(year(CURRENT_TIMESTAMP),2);
     
    		if((@inserted_year<>@lastcommande_year) OR (@max is null))
    		begin
    			select @max=0;
    		end
    		else
    		begin
    			select @max=@max+1;
    		end
     
    		select @prefix= 
    					case 
    						when @max<10 then '000'
    						when @max<100 then '00'
    						when @max<1000 then '0'
    						else ''
    					end		
     
    		insert into CommandeFournisseurs with (TABLOCK)
    		(ID,IDFournisseur,IDEtablissementLivraison,NumeroDevisFournisseur,CodeBonLivraisonRecu,CodeFactureRecu,RegleParDemandeur,
    		IDPersonneDemandeur,NumeroCommande,DateCommande,IDClient,IDDevise,Commentaire,CommentaireReception,CodeEtat,AutreFournisseur,
    		DelaiFournisseur,ReglementFournisseur,FaxFournisseur,TelephoneFournisseur,ContactFournisseur,LivraisonAdr1,LivraisonAdr2,LivraisonAdr3) 
     
    		select ID,IDFournisseur,IDEtablissementLivraison,NumeroDevisFournisseur,CodeBonLivraisonRecu,CodeFactureRecu,RegleParDemandeur,
    		IDPersonneDemandeur,@res,DateCommande,IDClient,IDDevise,Commentaire,CommentaireReception,CodeEtat,AutreFournisseur,
    		DelaiFournisseur,ReglementFournisseur,FaxFournisseur,TelephoneFournisseur,ContactFournisseur,LivraisonAdr1,LivraisonAdr2,LivraisonAdr3 from inserted
     
    end
    Mon problème est donc la requête d'insertion qui me paraît vraiment trop longue surtout pour définir le NumeroCommande qui est le seul affecté par ce trigger...

    Le champ ciblé NumeroCommande est défini à NOT NULL je ne peux donc pas faire d'UPDATE après l'insertion, je suis obligé de le définir à l'insertion d'où le INSTEAD OF.

    Puis-je faire la même chose sans être obligé de lister tous les champs de ma table ?

    Merci

  2. #2
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    733
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2003
    Messages : 733
    Billets dans le blog
    8
    Par défaut
    Votre Trigger comporte énormément d'erreurs graves !
    Il savoir, par exemple , que sous SQL Server les Trigger sont de type Statement et non pas de type Row. En d'autes termes, ils s'appliquent à un ensemble de lignes et non pas à une seule ligne (en l'occurrence plusieurs lignes la table CommandeFournisseurs peuvent être insérées à la fois ! ).

    Avant de faire du bricolage ! Je vous conseille vivement de lire l'excellent article de SQLPro et tout particulièrement la paragraphe "3.2. La solution : une table des clefs"
    http://sqlpro.developpez.com/cours/clefs/

    A+

  3. #3
    Membre confirmé
    Homme Profil pro
    Ingénieur Junior développement logiciels
    Inscrit en
    Mai 2014
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Junior développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 198
    Par défaut
    Je suis débutant dans le domaine.
    Je cherche juste à créer un Numero unique avec la valeur que je souhaite dans la table CommandeFournisseur.
    Je vais lire l'article en espérant trouver une réponse.

    Sinon je ne peux pas utiliser le système de computed value ou un système de séquence (dans ce genre la : http://sqlhints.com/2013/04/14/seque...l-server-2012/) que je pourrai utiliser à l'insertion et réinitialiser ?

    Il faut savoir que je cherche à générer un format de ce type : IC/140001

    IC/ ne change pas
    14 est l'année
    0001 est un id qui doit être réinitialisé à 0 lors du changement d'année.

    merci

  4. #4
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2003
    Messages
    733
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2003
    Messages : 733
    Billets dans le blog
    8
    Par défaut
    Citation Envoyé par Lionhart Voir le message
    ..Je cherche juste à créer un Numero unique avec la valeur que je souhaite dans la table CommandeFournisseur.
    Je vais lire l'article en espérant trouver une réponse.
    Dans un environnement multi-utilisateurs, où l'accès aux données est utltra-concurrentiel, la génération des clés uniques constituées sur une logique "Fonctionnelle" :
    Exemple :
    Concaténation de l'année +
    + 2 premières lettres du nom du client
    + L'âge de Jeanne-Antoinette Poisson, marquise de Pompadour
    + Max(xxx)
    + etc..

    est une affaire très délicate et très subtile. Et, j'ai vu beaucoup de développeurs se fourvoyer complètement sur le sujet ! aboutissant à des numéros de factures en double, à des numéros de commandes en double, etc. tout simplement parce qu'ils n'avaient rien compris à l'accès concurrentiel et aux niveaux d'isolation.
    L'article de SQLPro, que je vous ai indiqué va sur ce point vous éclairer sur le sujet. Vous pouvez ensuite personnaliser et adapter les exemples donnés dans l'article à vos propres besoins. L'important est de "distribuer" des clés uniques (dans votre cas, il s'agit d'initialiser la colonne NumeroCommande de la table CommandeFournisseurs avec une clé fonctionnelle unique) et c'est pas gagné d'avance !

    A+,

  5. #5
    Membre confirmé
    Homme Profil pro
    Ingénieur Junior développement logiciels
    Inscrit en
    Mai 2014
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Junior développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 198
    Par défaut
    L'important est de "distribuer" des clés uniques (dans votre cas, il s'agit d'initialiser la colonne NumeroCommande de la table CommandeFournisseurs avec une clé fonctionnelle unique) et c'est pas gagné d'avance !
    C'est bien pour cela que je suis ici et c'est aussi la raison pour laquelle j'essaie de gérer le NumeroCommande du côté SQL.

    J'ai bien lu l'article qui consiste à créer une table qui contient l'ID max.
    Ce qui me fera donc créer une table qui ne contient qu'une seule ligne et un TRIGGER FOR INSERT qui va modifier cette ligne en plus de la récupérer pour le mettre dans le numéro de commande.

    Je me suis donc permis de demander ceci :
    Sinon je ne peux pas utiliser le système de computed value ou un système de séquence (dans ce genre la : http://sqlhints.com/2013/04/14/seque...l-server-2012/) que je pourrai utiliser à l'insertion et réinitialiser ?

    Car la séquence sur un trigger d'insertion (qui permettra de réinitialiser la séquence en cas de changement d'année) me paraît intéressante.

  6. #6
    Membre Expert
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Par défaut
    Citation Envoyé par Lionhart Voir le message
    Je suis débutant dans le domaine.
    Je cherche juste à créer un Numero unique avec la valeur que je souhaite dans la table CommandeFournisseur.
    Je vais lire l'article en espérant trouver une réponse.
    Utilisez une colonne définie en IDENTITY.
    Vous la remettrez à 0 tous les ans, manifestement.

  7. #7
    Membre confirmé
    Homme Profil pro
    Ingénieur Junior développement logiciels
    Inscrit en
    Mai 2014
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Junior développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 198
    Par défaut
    Citation Envoyé par Rei Ichido Voir le message
    Utilisez une colonne définie en IDENTITY.
    Vous la remettrez à 0 tous les ans, manifestement.

    Le problème de ceci est le fait que je dispose déjà d'une clé primaire qui est un auto-incrément. Que je ne peux donc pas réinitialiser car clé primaire.

    Et surtout ceci :

    Plusieurs colonnes identité spécifiées pour la table 'test7'. Il n'est autorisé qu'une seule colonne identité par table.

  8. #8
    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
    Par défaut
    Bonjour,

    Quel est votre version de SQL Server ? à partir de 2012, vous pourriez utiliser les SEQUENCES.

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

Discussions similaires

  1. [TSQL] trigger inserted
    Par mous33 dans le forum Adaptive Server Enterprise
    Réponses: 4
    Dernier message: 31/10/2007, 13h46
  2. Trigger Insert Récupérer valeur autoincrément
    Par Silvia12 dans le forum Développement
    Réponses: 1
    Dernier message: 11/05/2007, 08h52
  3. 9i _ trigger insert
    Par laurent1 dans le forum Oracle
    Réponses: 8
    Dernier message: 28/03/2007, 14h44
  4. [trigger] insert update et delete
    Par kooljy dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 13/07/2006, 08h56
  5. trigger insert entre 2 serveurs
    Par Shabata dans le forum Développement
    Réponses: 5
    Dernier message: 27/05/2004, 12h00

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