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 :

Trigger à l'insertion


Sujet :

Développement SQL Server

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Mars 2016
    Messages : 28
    Points : 18
    Points
    18
    Par défaut Trigger à l'insertion
    Bonsoir
    j'ai un problème avec un trigger
    En effet j'ai une base de donnée dans laquelle j'ai deux tables A et B

    Avec A (Nom, prenom)
    Avec B (Nom, prenom, age, profession)

    NB: Nom et prénom est la clé primaire de A et clé étrangère de B
    De sortes que si le nom et prénom n'existe pas dans A on ne peut insérer les données dans B

    Je voudrais avant insertion des données dans la table B, récupérer Le nom et prénom avec trigger pour remplir A Avant B.

    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
    CREATE TRIGGER TRG_InsertActeur
    ON A
    FOR INSERT
    AS
    	BEGIN
    		DECLARE @Nom_acteur varchar(50)
    		DECLARE @Prenom_acteur varchar(50)
     
    		SET @Nom_acteur = 
    		(
    			SELECT NOM
    			FROM INSERTED
    		);
    		SET @Prenom_acteur = 
    		(
    			SELECT PRENOM
    			FROM INSERTED
    		);
    		BEGIN
                        INSERT INTO B (NOM, PRENOM) values (@Nom_acteur, @Prenom_acteur);
    		END
    	END
    GO
    INSERT INTO ACTEUR(Profession,Age, NOM, PRENOM) VALUES
    (
    	NULL, '50','Craig', 'Daniel'
    );

    Ce qui met le message d'erreur suivant
    L'instruction INSERT est en conflit avec la contrainte FOREIGN KEY "clé_étrangère_acteur". Le conflit s'est produit dans la base de données "videoclub", table "dbo.A".
    L'instruction a été arrêtée.
    Aidez moi à trouver la solution.
    Merci

  2. #2
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

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

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Bonjour,

    Dans ce cas, il faut que le trigger soit déclenché lors de l'insertion de données dans la table B, et non dans la table A.

    Ici, ton trigger se déclenche lors de l'insertion de données dans la table A et essaie d'ajouter des données dans la table B. Exactement le contraire de ce que tu souhaites faire !

    Il faut que ton trigger se déclenche lors de l'ajout d'enregistrements dans B. Par contre, tu vas devoir utiliser un trigger INSTEAD OF au lieu d'un FOR. Et ton trigger devra alors gérer l'insertion des données dans B après avoir vérifier l'existence de ces données dans A.

    Pour l'insertion de données, tu peux aussi regarder du côté des procédures stockées (ce qui me semblerait d'ailleurs plus adaptés dans ton cas).
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Mars 2016
    Messages : 28
    Points : 18
    Points
    18
    Par défaut
    Oui désolé j'ai fait une petite erreure en voulant partager le Trigger. Car en effet mon trigger devrait se déclencher comme tu l'as dit lors de l'insertion mais cela ne marche pas.
    j'ai éssayer en remplaçant 'FOR' par ' INSTEAD OF' mais malheureusement dans la table A, l'information est insérer mais pas dans la table B.
    Si vous pouvez me donner un exemple à suivre .....cela m'aiderait merci

  4. #4
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

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

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par midochel Voir le message
    j'ai éssayer en remplaçant 'FOR' par ' INSTEAD OF' mais malheureusement dans la table A, l'information est insérer mais pas dans la table B.
    Comme dit dans mon précédent message, il est nécessaire de réaliser l'insertion dans le trigger, car un trigger INSTEAD OF remplace le INSERT par l'exécution du trigger, tandis qu'un trigger FOR AFTER est déclenché une fois les enregistrements insérés.

    Donc ton trigger doit avoir 2 INSERTs : un qui vise la table A (c'est déjà le cas), un deuxième qui vise la table B.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Mars 2016
    Messages : 28
    Points : 18
    Points
    18
    Par défaut
    Merci j'ai compris le principe mais je suis un débutant dans l'utilisation de trigger et donc je ne sais comment inserer deux INSERTS dans un même trigger.
    Pourrais je avoir un exemple proche de mon problème.

  6. #6
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

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

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Tout simplement les uns derrières les autres.

    A noter également que les triggers sont ensemblistes, c'est-à-dire qu'une instruction INSERT qui insérerait 3 lignes n'appellera qu'une seule fois le trigger (et dans le trigger, la table INSERTED contiendra les 3 lignes). Actuellement, le trigger ne supporte pas cela.

    Enfin, le choix de la clé primaire n'est pas des plus adapté. En général, on évite des clés primaires sur des chaînes de caractères. Il vaut mieux utiliser une colonne autoincrémentée et ajouter une contrainte d'unicité englobant vos deux colonnes nom et prénom (en supposant qu'il ne peut donc y avoir d'homonyme). Outre le côté performance, ici d'un point de vue modélisation cela sera beaucoup mieux, puisque cela sera plus robuste aux changements de nom.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  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 779
    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 779
    Points : 52 754
    Points
    52 754
    Billets dans le blog
    5
    Par défaut
    Ce simple déclencheurt suffit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TRIGGER TRG_InsertActeur
    ON B
    INSTEAD OF INSERT
    AS
    SET NOCOUNT ON;
     
    INSERT INTO A SELECT Nom, Prenom FROM inserted;
    INSERT INTO B SELECT * FROM inserted;
    GO
    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
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Mars 2016
    Messages : 28
    Points : 18
    Points
    18
    Par défaut
    Merci ça marche

  9. #9
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

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

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Ce simple déclencheurt suffit
    Je le modifierai légèrement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TRIGGER TRG_InsertActeur
    ON B
    INSTEAD OF INSERT
    AS
    SET NOCOUNT ON;
     
    INSERT INTO A SELECT Nom, Prenom FROM inserted AS I WHERE NOT EXISTS (SELECT * FROM A WHERE nom = I.nom AND prenom = I.prenom)
    INSERT INTO B SELECT * FROM inserted;
    GO

    Car un acteur avoir plusieurs professions (acteur, réalisateur, etc...) et donc il ne doit être inséré dans la table A que s'il n'existe pas.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  10. #10
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Mars 2016
    Messages : 28
    Points : 18
    Points
    18
    Par défaut
    Bonjour
    Je viens pour un autre problème qui est une suite du début.
    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
    CREATE TRIGGER TRG_I
    ON B
    INSTEAD OF INSERT
    AS
    	DECLARE @Nom_realisateur varchar(50)
    	DECLARE @Prenom_realisateur varchar(50)
    	DECLARE @listeNoms VARCHAR(150)
     
    	SELECT @listeNoms = ISNULL(@listeNoms, '') + P.NOM + P.PRENOM + ',' + ','
    	FROM A P
    	JOIN INSERTED I
    		ON P.NOM = I.NOM AND P.PRENOM = I.PRENOM
     
    	SET @Nom_realisateur = 
    	(
    		SELECT NOM
    		FROM INSERTED
    	);
    	SET @Prenom_realisateur = 
    	(
    		SELECT PRENOM
    		FROM INSERTED
    	);
     
    	IF @listeNoms IS NOT NULL
    	BEGIN
    		print 'Ce realisateur ajouté est aussi un acteur'
    		INSERT INTO B SELECT * FROM inserted;
    	END
    	ELSE
    	BEGIN
    		print 'Le realisateur a bien été ajouté'
    		INSERT INTO A (NOM, PRENOM) values (@Nom_realisateur, @Prenom_realisateur);
    		INSERT INTO B SELECT * FROM inserted;
    	END
    GO
    Le code précédent fonctionne bien tant que A et B ont les même attributs .
    A (Nom, Prenom) , B(Nom, Prenom) Aussi Nom et prénom sont des clés primaires dans les deux tables.

    Cette fois lorsque je considère une autre table C dont la clé primaire est id, avec Nom, Prenom représente la clé étrangère qui reference la table A
    C(id, Nom, Prenom, sexe).

    Lorsque j'essais d'adapter ma requete comme précédent:

    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
    CREATE TRIGGER TRG_I
    ON C
    INSTEAD OF INSERT
    AS
    	DECLARE @Nom_realisateur varchar(50)
    	DECLARE @Prenom_realisateur varchar(50)
    	DECLARE @listeNoms VARCHAR(150)
     
    	SELECT @listeNoms = ISNULL(@listeNoms, '') + P.NOM + P.PRENOM + ',' + ','
    	FROM B P
    	JOIN INSERTED I
    		ON P.NOM = I.NOM AND P.PRENOM = I.PRENOM
     
    	SET @Nom_realisateur = 
    	(
    		SELECT NOM
    		FROM INSERTED
    	);
    	SET @Prenom_realisateur = 
    	(
    		SELECT PRENOM
    		FROM INSERTED
    	);
     
    	IF @listeNoms IS NOT NULL
    	BEGIN
    		print 'Ce realisateur ajouté est aussi un acteur'
    		INSERT INTO C SELECT * FROM inserted;
    	END
    	ELSE
    	BEGIN
    		print 'Le realisateur a bien été ajouté'
    		INSERT INTO B (NOM, PRENOM) values (@Nom_realisateur, @Prenom_realisateur);
    		INSERT INTO C SELECT * FROM inserted;
    	END
    GO
    Voici le message d'erreur que j'ai :
    Une valeur explicite de la colonne identité de la table 'C' ne peut être spécifiée que si la liste des colonnes est utilisée et si IDENTITY_INSERT est défini sur ON.



    Merci de m'aider à trouver une solution.
    Cordialement

  11. #11
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 779
    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 779
    Points : 52 754
    Points
    52 754
    Billets dans le blog
    5
    Par défaut
    Postez le DDL de vos table... Respectez la charte de postage :
    http://www.developpez.net/forums/d96...vement-poster/

    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/ * * * * *

  12. #12
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

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

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par midochel Voir le message
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    INSERT INTO C SELECT * FROM inserted;
    Je pense que le problème vient de là. Remplacez les * par les colonnes de la table C, sauf la colonne identité. Le * prend en compte toutes les colonnes, y compris la colonne identité, qui ne peut être insérée manuellement.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

Discussions similaires

  1. Insert avec select sur table avec Trigger d'insertion
    Par bran_noz dans le forum Développement
    Réponses: 5
    Dernier message: 23/12/2005, 14h38
  2. pb trigger lors insertion enregistrment!
    Par tooneygirl dans le forum Oracle
    Réponses: 9
    Dernier message: 06/12/2005, 22h57
  3. 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
  4. [trigger] update inserted?
    Par cosminutza dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 01/06/2005, 09h37
  5. Trigger et insert
    Par jf-nigou dans le forum Oracle
    Réponses: 5
    Dernier message: 16/02/2005, 16h45

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