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

Développement SQL Server Discussion :

Modifier inserted dans un trigger


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert

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

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 527
    Par défaut Modifier inserted dans un trigger
    Bonjour

    Je voudrais créer un trigger de type after insert sur une table clients.
    Dans ce trigger, je voudrais ajuster la valeur d'un champ de la ligne ajoutée en fonction d'une comparaison d'un des champs avec une autre table.
    Typiquement, selon la valeur d'un champ inséré, je vais chercher une valeur dans une autre table, et selon le résultat trouvé, j'ajuste cette valeur (ou pas).
    J'ai vu qu'il faut utiliser instead of plutôt qu'after pour avoir les champs AVANT l'insertion réelle.
    Ce que je n'arrive pas à comprendre, c'est si je peux modifier directement la valeur de la colonne en question dans inserted. Et dans ce cas, comment faire ? un "set inserted.monchamp = kekchose" me parait une étrange syntaxe. Comment faire (si c'est bien comme ça qu'il procéder).

    Merci d'avance de votre aide.

  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
    Citation Envoyé par Papy214 Voir le message
    Ce que je n'arrive pas à comprendre, c'est si je peux modifier directement la valeur de la colonne en question dans inserted. Et dans ce cas, comment faire ? un "set inserted.monchamp = kekchose" me parait une étrange syntaxe. Comment faire (si c'est bien comme ça qu'il procéder).
    NON, on ne modifie pas la pseudo table Inserted !!!

    Si vous utilisez un trigger de type INSTEAD OF INSERT il vous faudra insérer les données (remises en cause) dans la vraie table et non pas dans Inserted ! Considérez la table INSERTED comme une table "temporaire" contenant la sources des données à insérer AVANT leur remise en cause.

    Votre Trigger pourrait ressembler à ceci :

    Code 'SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    INSERT INTO dbo.Ma_Vraie_Table 
     (Id, Col1, Col2, ... ) 
     
    SELECT I.Id, .... , A.Coln, ...
     , CASE WHEN A.xxx... THEN ... END
     , .... 	 
    FROM INSERTED I 
    INNER JOIN dbo.Une_Autre_Table A 
     ON A.Id = I.Id
    NB : Attention à la clause de jointure INNER JOIN

    A+

  3. #3
    Membre Expert

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

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 527
    Par défaut
    Ok ! Donc, si j'ai bien compris, le trigger instead of va bloquer l'ajout de la ligne ?? ça ne va pas insérer deux fois les mêmes données ?

    Et si je fais un after insert, j'imagine que les données seront déjà dans la table. Dans ce cas, est-ce que je peux faire un update de la table sur le champ concerné en "lisant" la valeur du champ dans inserted ? Par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select @v from inserted
    select @valeur from table_reference where champ1 = @v
    if @v = 1 
      update tablecible set champ1 = 'Y'
    tablecible étant celle qui est concernée par le trigger.

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 998
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 998
    Billets dans le blog
    6
    Par défaut
    Les triggers SQL Server sont ensemblistes. or votre code présente des variables qui laissent à penser que vous n'aller traiter qu'une seule ligne. Ceci est totalement faux; En principe dan un trigger vous devriez n'avoir que des requêtes SQL.

    par exemple :
    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
     
    CREATE TRIGGER toto
    ON MATABLE
    AFTER INSERT
    AS
     
    UPDATE T
    SET    MaColonne = i.UneColonne - d.UneColonne
    FROM   MATABLE AS T
           INNER JOIN inserted AS i
    	         ON T.LaClef = i.LaClef
           INNER JOIN deleted AS d
    	         ON T.LaClef = i.LaClef
     
    GO
    Il serait plus intelligent que vous nous postiez le DDL de vos tables et un exemple de ce que vous voulez obtenir !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  5. #5
    Membre Expert

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

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 527
    Par défaut
    Bonjour

    Je voulais partir d'un exemple simple mais je vais m'expliquer un peu mieux.

    J'ai une table Catalogue qui définit les produits d'une société et pour laquelle on a les colonnes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    CREATE TABLE [dbo].[catalogue](
    	-- ...
    	[codeprix] [varchar](30) NULL,  
    	-- ...
    	[prixpromo] [varchar](10) NULL,  -- Y ou N
    	-- ...
    Table codesprix
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CREATE TABLE [dbo].[codeprix](
    	-- ...
    	[cppublic] [varchar](7) NULL,
    	-- ...
    	[cp5] [varchar](7) NULL,  -- Y ou N
    Lors de l'ajout d'un produit dans la table Catalogue, on me demande forcer prixpromo en fonction du code_prix s'il a été défini.
    Pour moi, il s'agissait de :
    1. Vérifier si codeprix a été défini (null est autorisé)
    2. Chercher dans la table codesprix la valeur de cp5 pour le codeprix défini
    3. Définir prixpromo dans Catalogue pour le nouveau produit en fonction du résultat (si trouvé pour cp5)



    Mais ce n'est peut-être pas possible dans un trigger.

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 998
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 998
    Billets dans le blog
    6
    Par défaut
    Pourquoi ne pas faire une simple intégrité référentielle ? Cela vous garantie que le lien existe toujours, sinon par trigger il faut en faire plusieurs dans chacune des tables !!!
    En sus pour votre colonne cp5, une simple vue avec jointure suffit. Une base n'est pas là pour faire de la redondance !!!

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

Discussions similaires

  1. deux Insert dans un trigger
    Par leanjocker dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 08/08/2013, 13h51
  2. Gérer toutes les lignes d'un update/insert dans un trigger
    Par Beluzzo dans le forum Développement
    Réponses: 2
    Dernier message: 25/10/2010, 17h30
  3. Réponses: 3
    Dernier message: 16/01/2009, 10h49
  4. Annuler une insertion dans un Trigger
    Par dreamanoir dans le forum Oracle
    Réponses: 2
    Dernier message: 10/01/2005, 13h04
  5. Recuperer derniere valeur modifiée dans un trigger
    Par xabs dans le forum Développement
    Réponses: 2
    Dernier message: 06/08/2004, 16h22

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