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

Administration SQL Server Discussion :

Problème de trigger


Sujet :

Administration SQL Server

  1. #1
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut Problème de trigger
    Bonjour,

    Je n'arrive pas à définir un trigger de manière ensembliste. Voici ce que je voudrais arriver à faire...

    Soit la table suivante :
    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
    CREATE TABLE [dbo].[T_CONTRACT_CTR](
        [CTR_ID] [int] IDENTITY(1,1) NOT NULL,
        [CTR_DATE] [date] NOT NULL,
        [BRA_ID] [int] NOT NULL,
        [DEP_ID] [smallint] NOT NULL,
        [SUP_ID] [int] NOT NULL,
     CONSTRAINT [PK_T_CONTRACT_CTR] PRIMARY KEY CLUSTERED 
    (
        [CTR_ID] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
     
    GO
     
    ALTER TABLE [dbo].[T_CONTRACT_CTR]  WITH CHECK ADD  CONSTRAINT [FK_T_CONTRACT_CTR_TJ_DEP_JSB_JDJ] FOREIGN KEY([DEP_ID], [BRA_ID], [SUP_ID])
    REFERENCES [dbo].[TJ_DEP_JSB_JDJ] ([DEP_ID], [BRA_ID], [SUP_ID])
    GO
     
    ALTER TABLE [dbo].[T_CONTRACT_CTR] CHECK CONSTRAINT [FK_T_CONTRACT_CTR_TJ_DEP_JSB_JDJ]
    GO
    Lors de l'insertion de nouvelles lignes, il faut que la date insérée dans la colonne CTR_DATE soit plus grande que toutes les autres valeurs de CTR_DATE pour le triple {DEP_ID, BRA_ID, SUP_ID}.

    Mais je n'arrive pas à formuler cette condition dans un IF.

    Mais p-e que je fais fausse route à la base.
    Kropernic

  2. #2
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Je pense y être finalement arriver avec 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
    IF EXISTS    (
                    SELECT    *
                    FROM    DBO.T_CONTRACT_CTR CTR
                                INNER JOIN inserted INS
                                    ON    CTR.BRA_ID = INS.BRA_ID
                                    AND    CTR.DEP_ID = INS.DEP_ID
                                    AND    CTR.SUP_ID = INS.SUP_ID
                                    AND    CTR.CTR_DATE > INS.CTR_DATE
                    )
            DELETE    
            FROM    DBO.T_CONTRACT_CTR
            WHERE    CTR_ID IN    (
                                SELECT    INS.CTR_ID
                                FROM    DBO.T_CONTRACT_CTR CTR
                                            INNER JOIN inserted INS
                                                ON    CTR.BRA_ID = INS.BRA_ID
                                                AND    CTR.DEP_ID = INS.DEP_ID
                                                AND    CTR.SUP_ID = INS.SUP_ID
                                                AND    CTR.CTR_DATE > INS.CTR_DATE)
    Kropernic

  3. #3
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    Hmm ton trigger ne fait pas ce que tu dis dans le postulat de départ

    Lors de l'insertion de nouvelles lignes, il faut que la date insérée dans la colonne CTR_DATE soit plus grande que toutes les autres valeurs de CTR_DATE pour le triple {DEP_ID, BRA_ID, SUP_ID}.
    Dans ton trigger si j'ai bien compris si tu trouves au moins une ligne dont la date est supérieure à celle insérée tu les supprimes ... est ce vraiment le comportement voulu ?

    ++

  4. #4
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Bah je me trouve dans l'after insert (car y avait déjà un trigger after insert pour insérer un truc dans une autre table alors autant l'utiliser).

    Donc si une ligne insérer contient une date avec une date plus petite que la date maximum pour le triplet{BRA_ID, SUP_ID, DEP_ID}, cela n'est pas valide donc je la supprime.

    A la base, je voulais tester cela dans une contrainte CHECK histoire de ne pas avoir à supprimer à posteriori mais je n'y suis pas arrivé .
    Kropernic

  5. #5
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    et pourquoi pas un trigger FOR INSERT et un ROLLBACK ?

    ++

  6. #6
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Citation Envoyé par mikedavem Voir le message
    et pourquoi pas un trigger FOR INSERT et un ROLLBACK ?

    ++
    Je crois que la réponse technique est "parce que j'suis un noob" .

    Je connaissais les triggers AFTER INSERT et INSTEAD OF INSERT mais pas FOR INSERT.

    Je testerai demain
    Kropernic

  7. #7
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 770
    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 770
    Points : 52 723
    Points
    52 723
    Billets dans le blog
    5
    Par défaut
    FOR INSERT = AFTER INSERT !

    Personnellement je testerais de la manière suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    WITH T0 AS
    (
    SELECT MAX(CTR_DATE) OVER(PARTITION BY DEP_ID, BRA_ID, SUP_ID) AS D, 
           DEP_ID, BRA_ID, SUP_ID
    FROM   dbo.T_CONTRACT_CTR)
    SELECT 1
    FROM   T0 
           INNER JOIN inserted AS i
                 ON T.CTR.BRA_ID = i.BRA_ID
                    AND T0.DEP_ID = i.DEP_ID
                    AND T0.SUP_ID = i.SUP_ID
                    AND T0.D > i.CTR_DATE
    IF @@ROWCOUNT > 0
       ROLLBACK;
    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/ * * * * *

  8. #8
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    Merci pour la précision Frédéric, je n'ai pas eu le temps de répondre à Kropernic --> AFTER = FOR.

    Le reste de la réponse est donné par SQLPro.

    ++

  9. #9
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    J'ai encore vraiment du mal avec les transactions...

    Sinon, c'est dangereux je trouve que FOR = AFTER. L'un est quand même le contraire de l'autre.

    On (les néophytes dont je fais partie) serait en droit de penser qu'un trigger FOR INSERT est déclenché AVANT l'insertion et non après...

    Vous ne trouvez pas ?
    Kropernic

  10. #10
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 770
    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 770
    Points : 52 723
    Points
    52 723
    Billets dans le blog
    5
    Par défaut
    En fait il n'y a pas de réel intérêt aux triggers BEFORE... C'est d'ailleurs même Sybase qui en 1986 à inventé les déclencheurs, bien avant qu'Oracle ne les introduise....
    Or compte tenu qu'il existe IDENTITY pour auto incrémenter, les déclencheurs BEFORE sont de peu d'utilité en sus d'être contre performant :
    • pour le préventif, utiliser les contraintes CHECK est généralement suffisant
    • les données n'étant pas encore présente dans la table il faut faire des UNION ALL avec la table cible avant de faire des jointures


    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. PL/SQL problème sur Trigger
    Par kitsune dans le forum PL/SQL
    Réponses: 4
    Dernier message: 06/12/2005, 20h35
  2. [9i] problème avec trigger after logon
    Par Michael# dans le forum Oracle
    Réponses: 2
    Dernier message: 17/03/2005, 12h14
  3. [Interbase6] Problème de triggers
    Par emeraudes dans le forum Bases de données
    Réponses: 4
    Dernier message: 08/03/2005, 09h52
  4. [SQLPLUS] - Problème de Triggers Java
    Par farcis dans le forum Oracle
    Réponses: 7
    Dernier message: 23/12/2004, 09h21
  5. [PL/SQL] problème de trigger
    Par Chuck67 dans le forum Oracle
    Réponses: 14
    Dernier message: 09/12/2004, 23h17

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