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

PostgreSQL Discussion :

[postgre] Trigger sur vue - héritage


Sujet :

PostgreSQL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2012
    Messages : 16
    Points : 12
    Points
    12
    Par défaut [postgre] Trigger sur vue - héritage
    Bonjour à tous,
    j'ai un problème pour la gestion d'héritage par trigger sur ma base de données.

    Il y a 2 table, Support, et DVD (table fille).
    support(ref,date_sortie,prix,duree,url,nb_dl)
    dvd(#ref,titre,syn)
    Le champ ref de support est auto incrementer.

    Ces 2 tables sont jointer dans la vue "vuedvd".

    Mes professeurs me demandes de gérer cet héritage par trigger.

    J'ai fait le trigger ci-dessous :

    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
    -- ---- Fonction
    CREATE OR REPLACE FUNCTION "Fct_InsertDvd"()
    	RETURNS trigger AS
    $BODY$
    BEGIN
    	INSERT INTO support(date_sortie,prix,duree,url,nb_dl)
    	VALUES (NEW.date_sortie,NEW.prix,NEW.duree,NEW.url,NEW.nb_dl)
    	RETURNING ref AS id;
    	INSERT INTO dvd(ref,titre,syn)
    	VALUES (id,NEW.titre,NEW.syn);
    END
    $BODY$
    	LANGUAGE plpgsql VOLATILE
    	COST 100;
    ALTER FUNCTION "Fct_InsertDvd"()
    	OWNER TO postgres;
    -- ---- Trigger
    CREATE TRIGGER InsertDvd
    	INSTEAD OF INSERT ON vuedvd
    	FOR EACH ROW
    	EXECUTE PROCEDURE "Fct_InsertDvd"();

    et lorsque j'envoie ma requête dans PgAdmin, j'ai ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ERREUR:  la requête n'a pas de destination pour les données résultantes
    État SQL :42601
    CONTEXT:  fonction PL/pgsql « Fct_InsertDvd », ligne 3 à instruction SQL
    le code erreur correspond à :
    42601 - Un caractère, une marque ou une clause est incorrect ou absent.

    Mais je ne vois pas ce qui est incorrect ou absent ... o.O

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Le problème est qu'il y a une clause RETURNING dans l'INSERT pour retourner le résultat dans une variable mais il n'y a aucune variable ni déclarée ni reliée au RETURNING.
    La version corrigée devrait ressembler à ça:
    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 OR REPLACE FUNCTION "Fct_InsertDvd"()
    	RETURNS TRIGGER AS
    $BODY$
    DECLARE
     i integer;
    BEGIN
    	INSERT INTO support(date_sortie,prix,duree,url,nb_dl)
    	VALUES (NEW.date_sortie,NEW.prix,NEW.duree,NEW.url,NEW.nb_dl)
    	RETURNING ref INTO i;
     
    	INSERT INTO dvd(ref,titre,syn)
    	VALUES (i,NEW.titre,NEW.syn);
    END
    $BODY$

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2012
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    merci de ta réponse, il y a en effet du mieux

    mais maintenant, il me réponds :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ERREUR: le contrôle a atteint la fin de la procédure trigger sans RETURN
    État SQL :2F005
    Contexte : fonction PL/pgsql « Fct_InsertDvd »
    apparemment, c'est le returning qui ne le plait pas.

    ---- EDIT ----

    bon, j'ai essayé de remplacer le returning par une requete voila ce que sa donne :
    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 OR REPLACE FUNCTION "Fct_InsertDvd"()
    	RETURNS trigger AS
    $BODY$
    DECLARE
    	i integer;
    BEGIN
    	INSERT INTO support(date_sortie,prix,duree,url,nb_dl)
    	VALUES (NEW.date_sortie,NEW.prix,NEW.duree,NEW.url,NEW.nb_dl);
     
    	PERFORM lastval() as i
    	FROM support;
     
    	INSERT INTO dvd(ref,titre,syn)
    	VALUES (i,NEW.titre,NEW.syn);
    END
    $BODY$
    	LANGUAGE plpgsql VOLATILE
    	COST 100;
    ALTER FUNCTION "Fct_InsertDvd"()
    	OWNER TO postgres;
    là, postgre me dit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ERREUR: une valeur NULL viole la contrainte NOT NULL de la colonne « ref »
    État SQL :23502
    Contexte : instruction SQL « INSERT INTO dvd(ref,titre,syn)
    	VALUES (i,NEW.titre,NEW.syn) »
    PL/pgSQL function "Fct_InsertDvd" line 9 at instruction SQL
    ---- EDIT ----
    Là j'ai essayé de le faire grâce à une autre fonction:

    La fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE OR REPLACE FUNCTION "SupportLastVal"()
      RETURNS integer AS
    $BODY$
    BEGIN
    	SELECT lastval()
    	FROM support;
    END
    $BODY$
      LANGUAGE plpgsql VOLATILE
      COST 100;
    le trigger
    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
    CREATE OR REPLACE FUNCTION "Fct_InsertDvd"()
      RETURNS trigger AS
    $BODY$
    DECLARE
    i integer;
    BEGIN
    	INSERT INTO support(date_sortie,prix,duree,url,nb_dl)
    	VALUES (NEW.date_sortie,NEW.prix,NEW.duree,NEW.url,NEW.nb_dl);
     
    	INSERT INTO dvd(ref,titre,syn)
    	VALUES (SupportLastVal(),NEW.titre,NEW.syn);
    END
    $BODY$
      LANGUAGE plpgsql VOLATILE
      COST 100;
    ALTER FUNCTION "Fct_InsertDvd"()
      OWNER TO postgres;
    La réponse lors d'une insertion
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ERREUR: la fonction supportlastval() n'existe pas
    État SQL :42883
    Astuce : Aucune fonction ne correspond au nom donné et aux types d'arguments.
    Vous devez ajouter des conversions explicites de type.
    Contexte : PL/pgSQL function "Fct_InsertDvd" line 10 at instruction SQL

    En effet, lorsque je regarde dans l’arborescence de postgre, il n'y a pas ma fonction.
    Mais lors de sa création il m'avait dit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    La requête a été exécutée avec succès en 10 ms, mais ne renvoie aucun résultat.
    o.O

  4. #4
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Bonjour,

    Il faut rajouter "return null".

    Et binder votre trigger en mode "instead of insert on ma_vue for each row".


    Quand vous utiliserez un trigger sur une table, par exemple pour changer une valeur, vous aurez 2 possibilités :
    - return new => le changement ce fera (commit)
    - return null => aucun changement ne se fera (rollback)

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2012
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par punkoff Voir le message
    Et binder votre trigger en mode "instead of insert on ma_vue for each row".
    oui, j'avais déjà mis mon trigger sous cette forme.


    Citation Envoyé par punkoff Voir le message
    Il faut rajouter "return null".
    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
    CREATE OR REPLACE FUNCTION "Fct_InsertDvd"()
      RETURNS trigger AS
    $BODY$
    DECLARE
    i integer;
    BEGIN
    	INSERT INTO support(date_sortie,prix,duree,url,nb_dl)
    	VALUES (NEW.date_sortie,NEW.prix,NEW.duree,NEW.url,NEW.nb_dl);
     
    	PERFORM lastval() as i
    	FROM support;
     
    	return new;
     
    	INSERT INTO dvd(ref,titre,syn)
    	VALUES (i,NEW.titre,NEW.syn);
    END
    $BODY$
      LANGUAGE plpgsql VOLATILE
      COST 100;
    ALTER FUNCTION "Fct_InsertDvd"()
      OWNER TO postgres;
    si je le met ici, la table support est en effet modifier par l'INSERT, mais pas la table dvd.
    Et si je le met après le INSERT INTO dvd, j'ai toujours le même problème. o.O

  6. #6
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    avant le end (et mettez un point virgule)

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2012
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    merci pour ton aide Punkoff, alors voici mes modification.

    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
    CREATE OR REPLACE FUNCTION "Fct_InsertDvd"()
      RETURNS trigger AS
    $BODY$
    DECLARE
    i integer;
    BEGIN
    	INSERT INTO support(date_sortie,prix,duree,url,nb_dl)
    	VALUES (NEW.date_sortie,NEW.prix,NEW.duree,NEW.url,NEW.nb_dl);
     
    	PERFORM lastval() as i
    	FROM support;
     
    	INSERT INTO dvd(ref,titre,syn)
    	VALUES (i,NEW.titre,NEW.syn);
     
    	return null;
    END
    $BODY$
      LANGUAGE plpgsql VOLATILE
      COST 100;
    ALTER FUNCTION "Fct_InsertDvd"()
      OWNER TO postgres;
    lors de l'insertion:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ERREUR: une valeur NULL viole la contrainte NOT NULL de la colonne « ref »
    État SQL :23502
    Contexte : instruction SQL « INSERT INTO dvd(ref,titre,syn)
    	VALUES (i,NEW.titre,NEW.syn) »
    PL/pgSQL function "Fct_InsertDvd" line 11 at instruction SQL
    j'ai essayer avec new et null

  8. #8
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Pourquoi n'utilisez-vous pas la syntaxe avec returning que vous a mit estofilo ?

    C'est celle qu'il faut utiliser.

  9. #9
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2012
    Messages : 16
    Points : 12
    Points
    12
    Par défaut

    En effet, ça marche beaucoup mieux

    voici le code final qui fonctionne :
    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
    CREATE OR REPLACE FUNCTION "Fct_InsertDvd"()
      RETURNS trigger AS
    $BODY$
    DECLARE
    i integer;
    BEGIN
    	INSERT INTO support(date_sortie,prix,duree,url,nb_dl)
    	VALUES (NEW.date_sortie,NEW.prix,NEW.duree,NEW.url,NEW.nb_dl)
    	RETURNING ref INTO i;
     
    	PERFORM lastval() as i
    	FROM support;
     
    	INSERT INTO dvd(ref,titre,syn)
    	VALUES (i,NEW.titre,NEW.syn);
     
    	return new;
    END
    $BODY$
      LANGUAGE plpgsql VOLATILE
      COST 100;
    ALTER FUNCTION "Fct_InsertDvd"()
      OWNER TO postgres;
    MERCI BEAUCOUP, je n'y serai jamais arrivé sans vous

  10. #10
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    a quoi vous sert le perform ?

    Vous savez ce que ça fait ?

    là cette requête ne fait rien du tout je pense

  11. #11
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2012
    Messages : 16
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par punkoff Voir le message
    a quoi vous sert le perform ?
    le perform remplace un select dans certain cas.
    mais en effet là ça ne sert à rien o.O

    je l'ai mis à un moment pour tester et j'ai oublier de l'enlever, merci

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

Discussions similaires

  1. Trigger sur vue : problème à l'insertion
    Par edim34 dans le forum PL/SQL
    Réponses: 1
    Dernier message: 29/06/2015, 10h27
  2. Trigger sur vue
    Par amani1 dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 22/01/2014, 16h49
  3. Trigger sur vue avec appli dédiée
    Par havener dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 22/07/2009, 16h21
  4. TRIGGER sur une vue
    Par islamune9 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 18/09/2007, 18h32
  5. Pb Trigger sur vue
    Par cosminutza dans le forum Développement
    Réponses: 3
    Dernier message: 28/07/2003, 17h37

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