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 :

[SQL Server 2000][Trigger] modifier 1 autre table après la mise à jour


Sujet :

MS SQL Server

  1. #1
    Membre du Club
    Inscrit en
    Novembre 2004
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 58
    Points : 62
    Points
    62
    Par défaut [SQL Server 2000][Trigger] modifier 1 autre table après la mise à jour
    Bonjour
    J'ai un petit souci :
    Je dois assurer l'intégrité des données de 2 appli qui stockent et lisent chacune dans deux tables.

    Puisqu'elles partagent plusieurs champs en commun (mais n'ont aucune relation de clés étrangères), je veux qu'à la mise à jour d'un des champs en commun d'une des tables, l'autre soit mise à jour.

    Donc un trigger after update semble le plus judicieux.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    If Update(ville) or Update(codePostal) or Update(...) 
    Begin
    Mais si je met ce genre de trigger sur les 2 tables (puisque les mises à jour peuvent se faire sur l'une ou l'autre des tables), ça risque de coincer non? puisque les 2 trigger after update se déclencheront mutuellement, et de manière cylique....

    Mais je ne vois pas comment régler le problème... Si quelqu'un pouvait m'éclairer ce serait gentil merci

  2. #2
    Membre éprouvé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Août 2006
    Messages
    730
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

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

    Informations forums :
    Inscription : Août 2006
    Messages : 730
    Points : 923
    Points
    923
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IF UPDATE(ville) OR UPDATE(codePostal) OR UPDATE(...) 
    Begin
    le if update te dis si ta colonne a été modifiée, OK
    il te suffit donc de tester aussi si inserted=deleted

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    IF UPDATE(ville) 
    Begin
    if exists(select ins.ville from inserted ins
    join deleted del  on ins.key=del.key
    where ins.ville<>del.ville)
      --code de mise a jour
    end
    Errare humanum est, perseverare diabolicum (Sénèque)

  3. #3
    Membre du Club
    Inscrit en
    Novembre 2004
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 58
    Points : 62
    Points
    62
    Par défaut
    Merci de cette réponse complète mais pour l'update je ne vois pas en quoi cela règle le pb d'appel cyclique (peut-être que je n'ai pas les yeux en face des trous et si c'est le cas désolé )

    Mon pb :
    j'ai une table T1 avec ID_T1,Ville_T1,CodePostal_T1,...
    sur cette table, j'ai un trigger qui après la mise à jour , et si l'un des champs ville ou code postal a été modifié doit mettre à jour la table T2

    j'ai une table T2 pour l'exemple avec ID_T2,Ville_T2,CodePostal_T2,...
    et j'ai le meme trigger après mise à jour d'un des champs ville_T2 ou codePostal_T2 doit mettre à jour les champs de T1 .

    Comment faire pour que le trigger sur T1 qui contiendra un update de T2 ne déclenche pas le trigger after update de T2 (qui contiendra un update de T1) ?

    (En tout cas en relisant ta réponse, elle me permet de répondre à une autre question et m'apporte la solution adéquate donc déjà merci)

  4. #4
    Membre éprouvé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Août 2006
    Messages
    730
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

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

    Informations forums :
    Inscription : Août 2006
    Messages : 730
    Points : 923
    Points
    923
    Par défaut
    supposons
    id_T1=100
    id_T2=200

    requete appliquée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    update T1 set Ville_T1='TOULOUSE' where id_T1=100
    le trigger sur T1 va mettre a jour T2 en appliquant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    update T2 set Ville_T2='TOULOUSE' where id_T2=200
    le trigger sur T2 va mettre a jour T1 en appliquant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    update T1 set Ville_T1='TOULOUSE' where id_T1=100
    mais inserted.Ville_T1=deleted.Ville_T1='TOULOUSE' donc le le trigger sur T2 ne fera rien !!
    Errare humanum est, perseverare diabolicum (Sénèque)

  5. #5
    Membre du Club
    Inscrit en
    Novembre 2004
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 58
    Points : 62
    Points
    62
    Par défaut
    Merci d'avoir gentiment réexpliqué je n'avais pas vu ça comme ça
    merci pour l'exemple
    c'est exactement ce que je cherchais

    bref merci pour ce temps passé

    bonne soirée

  6. #6
    Membre du Club
    Inscrit en
    Novembre 2004
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 58
    Points : 62
    Points
    62
    Par défaut Cycle !
    Oups par contre j'ai cette erreur quand je modifie depuis enterprise manager :



    Mon schéma :

    T1
    IDT1
    nom
    prenom
    numtel

    T2
    IDT2
    nom
    adresse

    T3
    IDT3
    nom
    numtel
    statut_marital
    date_naissance

    ASSOCIATION
    T1_ID
    T2_ID
    T3_ID

    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
     
    CREATE TRIGGER mise_a_jour_T1 ON [dbo].[T1] 
    AFTER UPDATE
    AS
     
    IF UPDATE(nom) 
    Begin
        IF EXISTS(SELECT ins.nom FROM inserted ins
        JOIN deleted del  ON ins.IDT1=del.IDT1
        WHERE ins.nom<>del.nom)
     
            Update T2 set nom = (Select nom from inserted)
            Where T2.IDT2 in (Select T2_ID
            From ASSOCIATION Where T1_id = (Select inserted.IDT1 from inserted))
     
            Update T3 set nom = (Select nom from inserted)
            Where T3.IDT3 in (Select T3_ID
            From ASSOCIATION Where T1_id = (Select inserted.IDT1 from inserted))
    end
    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
     
    CREATE TRIGGER mise_a_jour_T2 ON [dbo].[T2] 
    AFTER UPDATE
    AS
     
    IF UPDATE(nom) 
    Begin
        IF EXISTS(SELECT ins.nom FROM inserted ins
        JOIN deleted del  ON ins.IDT2=del.IDT2
        WHERE ins.nom<>del.nom)
     
            Update T1 set nom = (Select nom from inserted)
            Where T1.IDT1 in (Select T1_ID
            From ASSOCIATION Where T2_id = (Select inserted.IDT2 from inserted))
     
            Update T3 set nom = (Select nom from inserted)
            Where T3.IDT3 in (Select T3_ID
            From ASSOCIATION Where T2_id = (Select inserted.IDT2 from inserted))
    end
    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
     
    CREATE TRIGGER mise_a_jour_T3 ON [dbo].[T3] 
    AFTER UPDATE
    AS
     
    IF UPDATE(nom) 
    Begin
        IF EXISTS(SELECT ins.nom FROM inserted ins
        JOIN deleted del  ON ins.IDT2=del.IDT3
        WHERE ins.nom<>del.nom)
     
            Update T1 set nom = (Select nom from inserted)
            Where T1.IDT1 in (Select T1_ID
            From ASSOCIATION Where T3_id = (Select inserted.IDT3 from inserted))
     
            Update T2 set nom = (Select nom from inserted)
            Where T2.IDT2 in (Select T2_ID
            From ASSOCIATION Where T2_id = (Select inserted.IDT2 from inserted))
    end

    Je comprends donc bien, le pourquoi de la récurrence indirecte, mais je ne vois pas comment l'annuler....

  7. #7
    Expert confirmé
    Avatar de rudib
    Homme Profil pro
    Fakir SQL Server & NoSQL
    Inscrit en
    Mai 2006
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Fakir SQL Server & NoSQL

    Informations forums :
    Inscription : Mai 2006
    Messages : 2 573
    Points : 4 043
    Points
    4 043
    Par défaut
    Bonjour,

    Pour désactiver la récursion directe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ALTER DATABASE mabase
       SET RECURSIVE_TRIGGERS OFF
    Pour désactiver la récursion indirecte, en les imbrications :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    EXEC sp_configure 'nested triggers', '0'
    RECONFIGURE WITH OVERRIDE
    Rudi Bruchez
    Rudi Bruchez EIRL, solutions MS SQL Server et NoSQL
    LinkedIn - [Outil libre de diagnostic SQL Server : Sql Trismegiste]
    LIVRES : Optimiser SQL Server -
    Microsoft SQL Server 2012 Security Cookbook
    - les bases de données NoSQL

    e-learning : LinkedIn Learning - Pluralsight

  8. #8
    Membre du Club
    Inscrit en
    Novembre 2004
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 58
    Points : 62
    Points
    62
    Par défaut
    Merci pour cette réponse rapide!
    Cependant, si je désactive la récurrence indirecte, je comprends par là que mes autres triggers déclenchés par l'appel du premier ne seront pas appelés.... peut-être que c'est là que je comprends mal l'option... (je l'avais lu sur la msdn...)
    Et dans ce cas, ça ne résoud pas le problème...
    Merci de m'éclairer...

  9. #9
    Membre du Club
    Inscrit en
    Novembre 2004
    Messages
    58
    Détails du profil
    Informations forums :
    Inscription : Novembre 2004
    Messages : 58
    Points : 62
    Points
    62
    Par défaut Réponse
    Désolé de n'indiquer ça que très tardivement mais j'ai finalement trouvé la réponse sur un autre forum. Je vous la livre telle quelle :

    Bonjour,

    Je pense qu'il y a 2 possibilités :

    Utiliser des triggers INSTEAD OF qui présente l'avantage d'éviter le problème de récusivité, par contre il ne peut y en avoir qu'un par type de modification et il n'est pas simple de les mettre en place.

    ou

    Désactiver les triggers des autres table ou début du code du 1er trigger par

    -- Le Trigger NomTrigger
    alter table NomTable disable trigger NomTrigger

    -- Tous les triggers
    alter table NomTable disable trigger all

    Et là le problème est régle, il faudra bien penser à réactiver ces Triggers par enable à la fin du code.

    Cordialement,
    Encore merci !

  10. #10
    Membre du Club
    Inscrit en
    Février 2009
    Messages
    53
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 53
    Points : 44
    Points
    44
    Par défaut
    merci
    c'était ça , ça a marcher

    je savais pas qu'on pouvait désactivé des triggers

    je me coucherais moins *** se soir merci

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 02/05/2011, 14h30
  2. [SQL Server 2000] Convertir base ou table en utf-8
    Par lnhf dans le forum MS SQL Server
    Réponses: 10
    Dernier message: 02/12/2009, 12h05
  3. [SQL Server 2005]Trigger DDL -> Nom Table Modifiée
    Par Yotho dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 26/06/2007, 11h11
  4. [SQL SERVER 2000][Trigger] Pb lors de l'execution du trigger
    Par mcousse dans le forum Développement
    Réponses: 4
    Dernier message: 24/11/2006, 11h25
  5. [SQL Server 2000] Changer le propriétaire de table en 'dbo'
    Par MatthieuQ dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 03/05/2005, 14h24

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