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 :

before insert trigger en sql


Sujet :

MS SQL Server

  1. #1
    Membre averti
    Inscrit en
    Novembre 2009
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 29
    Par défaut before insert trigger en sql
    bonsoir a tous,

    j ai encore un probleme en sql. j ai une table client (nom, adresse) et j aimerai creer un trigger qui verifie d abord l adresse avant d inserer, mais j ai l erreur suivante : 'before' is not a recognized trigger. j aimerai donc savoir si un before insert est possible, si oui comment. merci de votre reponse

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

    Avec SQL Server il n'y a pas de trigger BEFORE, et vous verrez qu'en fait, vous n'en avez pas besoin: utilisez un trigger INSTEAD OF.

    Voici un peu de lecture sur les triggers

    Je ne sais pas quel type de vérification vous souhaitez faire sur l'adresse, mais s'il s'agit par exemple d'un format, vous pouvez le gérer avec une contrainte de domaine (CHECK).

    @++

  3. #3
    Membre averti
    Inscrit en
    Novembre 2009
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 29
    Par défaut
    bonsoir elsuket,

    [CODE= sql]en faire j aimerais d abord verifier si le nom entre existe deja si oui alors j envoie un message du genre "ce nom existe deja", sinon je l enregistre. avec INSTEAD OF, j ai lu mais pas vraiment compris a quoi ca sert et pourquoi et comment l utiliser. si tu peux l utiliser dans mon cas, je crois que ca pourra m aider a mieux comprendre.

    merci d avance

  4. #4
    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 : 43
    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
    Par défaut
    Dans ce cas ajoutez une contrainte d'unicité sur le nom :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ALTER TABLE dbo.client
    ADD CONSTRAINT UQ_client_nom UNIQUE (nom)
    Mais êtes-vous sûr que le nom du client pourra rester unique ?
    Je ne connais la problématique de votre base de données, mais il se peut aussi que vous ayez aussi deux clients distincts ayant même adresse ...

    En utilisant un trigger, on aurait :

    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
    CREATE TRIGGER TR_IOF_I_client
    	ON dbo.client
    INSTEAD OF INSERT
    AS
    BEGIN
    	-- Concatène la liste des noms qu'on tente d'insérer
    	-- mais qui sont déjà dans la table client
    	DECLARE @listeNoms VARCHAR(128)
    	SELECT @listeNoms = ISNULL(@listeNoms, '') + C.nom + ','
    	FROM dbo.client AS C
    	JOIN INSERTED AS I
    		ON C.nom = I.nom
     
    	-- Si la liste n'est pas vide, on lève une exception
    	IF @listeNoms IS NOT NULL
    	BEGIN
    		SELECT @listeNoms = LEFT(@listeNoms, LEN(@listeNoms) - 1)
    		RAISERROR('Les noms %s existent déjà !', 16, 1, @listeNoms)
     
    		ROLLBACK
    	END
    	ELSE -- Sinon on procède à l'insertion
    	BEGIN
    		INSERT INTO dbo.client
    		(
    			colonnesDeLaTableClient
    		)
    		SELECT colonnesDeLaTableClient
    		FROM INSERTED
    	END
    END
    Mais comme vous le voyez, nous devrons pour toute nouvelle insertion réaliser une jointure sur le nom du client.
    Or, réaliser une jointure sur une chaîne de caractère est bien moins performant qu'une jointure sur des entiers, même si celle-ci est indexée ...

    Néanmoins, tout dépend du nombre de clients que vous aurez quand la base de données sera arrivée à maturité (3-5 ans ...)

    @++

  5. #5
    Membre averti
    Inscrit en
    Novembre 2009
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 29
    Par défaut
    Code sql : 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
    j ai 2 encore 2 questions:
     
    1- qu est ce que nous apporte le instead of insert?
     
    2- quand tu fais ceci: 
    ELSE -- Sinon on procède à l'insertion
    	BEGIN
    		INSERT INTO dbo.client
    		(
    			colonnesDeLaTableClient
    		)
    		SELECT colonnesDeLaTableClient
    		FROM INSERTED
    	END
     
    est ce que ca ne signifie pas que on insert dans la tableclient tous les enregistrements de la table inserted?
    je ne comprend pas bien ce que fais ce petit bout de code.
     
    merci encore pour tes reponses

  6. #6
    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 : 43
    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
    Par défaut
    qu est ce que nous apporte le instead of INSERT?
    Les triggers de type INSTEAD OF permettent de n'effectuer qu'une seule modification sur une table au lieu de deux, par exemple un trigger AFTER INSERT qui ferait dans son code un UPDATE sur la même table.

    Il permet aussi, comme je vous l'ai montré dans le trigger que je vous propose, d'effectuer des vérifications avant de modifier la table cible.

    quand tu fais ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ELSE -- Sinon on procède à l'insertion
    	BEGIN
    		INSERT INTO dbo.client
    		(
    			colonnesDeLaTableClient
    		)
    		SELECT colonnesDeLaTableClient
    		FROM INSERTED
    	END
    est ce que ca ne signifie pas que ON INSERT dans la tableclient tous les enregistrements de la TABLE inserted?
    je ne comprend pas bien ce que fais ce petit bout de code.
    Quand un trigger INSTEAD OF s'exécute, si on ne re-spécifie pas la modification de données à effectuer qui aurait du être faite si le trigger n'existait pas sur la table, alors l'effet de cette modification est perdu.

    Si vous avez lu les deux liens que je vous ai donné sur les triggers, vous savez à quoi servent les tables virtuelles INSERTED et DELETED.

    @++

  7. #7
    Membre averti
    Inscrit en
    Novembre 2009
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 29
    Par défaut
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    bonjour,
     
    quand tu fais ceci, c la mon probleme:
     
    ELSE -- Sinon on procède à l'insertion
    	BEGIN
    		INSERT INTO dbo.client
    		(
    			colonnesDeLaTableClient
    		)
    		SELECT colonnesDeLaTableClient
    		FROM INSERTED
    	END
     
    mais est ce que c n est pas apres avoir utilise le "insert into" que dans la table inserted ira s enregistrer la donnee. car avec la boucle qui est la au dessus j ai l impression la donnee est deja dans la table inserted.

  8. #8
    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 : 43
    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
    Par défaut
    Ne mettez pas tout dans la balise code, ça devient illisible

    mais est ce que c n est pas apres avoir utilise le "insert into" que dans la TABLE inserted ira s enregistrer la donnee. car avec la boucle qui est la au dessus j ai l impression la donnee est deja dans la TABLE inserted.
    INSERTED est une table virtuelle dont la structure est strictement la même que la table cible, et qui contient, dans le cas d'une insertion, les lignes qui allaient être insérées dans la table.
    Donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    INSERT INTO dbo.client
    (
    	colonnesDeLaTableClient
    )
    SELECT colonnesDeLaTableClient
    FROM INSERTED
    Insère effectivement dans la tables les lignes qui allaient l'être.
    Si on ne met pas ce code, aucune ligne ne sera insérée dans la table

    @++

  9. #9
    Membre averti
    Inscrit en
    Novembre 2009
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 29
    Par défaut
    rebonjour,

    vous dites ceci :INSERTED est une table virtuelle dont la structure est strictement la même que la table cible, et qui contient, dans le cas d'une insertion, les lignes qui allaient être insérées dans la table.

    donc cela signifie que si je fais 100 INSERT INTO, j aurai aussi 100 donnees enregistrees dans la table INSERTED? ou alors c la dernier donnee qui restera dans la table?

  10. #10
    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 : 43
    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
    Par défaut
    ça dépend

    Si vous faites 100 INSERT d'une ligne, le trigger est exécuté 100 fois et la table virtuelle INSERTED contiendra à chaque fois une ligne.

    Si vous faites un INSERT de 100 lignes, la table virtuelle INSERTED contiendra 100 lignes.

    Sous SQL Server, les triggers sont ensemblistes

    Faites donc les petits exemples qui sont dans le second lien pour voir comment les tables virtuelles se comportent

    @++

  11. #11
    Membre averti
    Inscrit en
    Novembre 2009
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 29
    Par défaut
    Bonjour elsuket,

    concernant la table INSERTED, je pense d apres la logique que la table INSERTED ne contient que la derniere ligne ajoutee, puisqu on ne peut pas la parcourir.
    bon j ai encore une autre question: comment tester si un utilisateur a les droits sur une table (SELECT, INSERT; UPDATE; DELETE)

  12. #12
    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 : 43
    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
    Par défaut
    concernant la table INSERTED, je pense d apres la logique que la table INSERTED ne contient que la derniere ligne ajoutee, puisqu on ne peut pas la parcourir.
    Je vous l'ai dit : cela est faux.
    Si vous aviez lu le lien que je vous ai proposé et fait le test qui je donne, vous vous en seriez forcément rendu compte

    Si nous exécutons :

    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
    CREATE TABLE TbTestTrigger
    (
    	val TINYINT
    )
    GO
     
    CREATE TRIGGER TR_A_I_TbTestTrigger
    	ON dbo.TbTestTrigger
    	AFTER INSERT
    AS
    BEGIN
    	SELECT val
    	FROM INSERTED
    END
    GO
     
    INSERT INTO dbo.TbTestTrigger (val)
    	SELECT 1
    UNION
    	SELECT 2
    UNION
    	SELECT 3
    UNION
    	SELECT 4
    UNION
    	SELECT 5
    Nous obtenons :

    val
    ---
    5
    4
    3
    2
    1
    Qu'entendez-vous par parcourir ?
    Auriez-vous spécifié un curseur ou une boucle WHILE dans votre trigger ?

    @++

  13. #13
    Membre averti
    Inscrit en
    Novembre 2009
    Messages
    29
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 29
    Par défaut
    ok ca va merci, mon probleme est resolu.

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

Discussions similaires

  1. [Ora9207] Before insert trigger <> blob field
    Par Vld44 dans le forum PL/SQL
    Réponses: 6
    Dernier message: 07/11/2008, 16h40
  2. Trigger : Before insert
    Par guitou0 dans le forum Développement
    Réponses: 6
    Dernier message: 29/06/2007, 11h39
  3. Trigger Before Insert
    Par Fred_ET dans le forum Administration
    Réponses: 7
    Dernier message: 22/11/2006, 00h29
  4. Créer un trigger "before insert" avec SQL Server
    Par bubi dans le forum Développement
    Réponses: 2
    Dernier message: 14/11/2005, 10h12
  5. Insertion dans table SQL server (Trigger) Aidz moi SVP????
    Par pop bob dans le forum Développement
    Réponses: 2
    Dernier message: 30/07/2005, 23h55

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