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

Requêtes PostgreSQL Discussion :

Trigger sur une vue pour remplir des clé secondaires


Sujet :

Requêtes PostgreSQL

  1. #1
    Membre à l'essai
    Femme Profil pro
    Géomaticienne
    Inscrit en
    Juillet 2018
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Géomaticienne
    Secteur : Service public

    Informations forums :
    Inscription : Juillet 2018
    Messages : 18
    Points : 11
    Points
    11
    Par défaut Trigger sur une vue pour remplir des clé secondaires
    Bonjour,

    Je travaille sous Postgre et je dispose de 2 tables (TableA et TableB) :

    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
    CREATE TABLE TableA
    (
      id_A integer NOT NULL DEFAULT nextval('seq_A'::regclass),
      geom geometry(Point,2154),
      num_A character varying(10),
     
      CONSTRAINT pk_id_A PRIMARY KEY (id_A),
      CONSTRAINT enforce_geotype_geom CHECK (st_geometrytype(geom) = 'ST_Point'::text OR geom IS NULL),
      CONSTRAINT enforce_srid_geom CHECK (st_srid(geom) = 2154)
    )
    WITH (
      OIDS=TRUE
    );
    ALTER TABLE TableA
      OWNER TO sig;
    GRANT ALL ON TABLE TableA TO sig;
    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
    CREATE TABLE TableB
    (
      id_B integer NOT NULL DEFAULT nextval('seq_B'::regclass),
      num_B character varying(10),
      A_id integer),
     
      CONSTRAINT pk_id_B PRIMARY KEY (id_B),
      CONSTRAINT fk_B FOREIGN KEY (A_id)
          REFERENCES TableA (id_A) MATCH SIMPLE
          ON UPDATE CASCADE ON DELETE CASCADE
    WITH (
      OIDS=TRUE
    );
    ALTER TABLE TableB
      OWNER TO sig;
    GRANT ALL ON TABLE TableB TO sig;

    J'ai mis en place une Vue (MaVue), afin de consulter tous les champs de mes 2 tables,
    Cette vue comprend également un Trigger (MonTrigger):

    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 OR REPLACE VIEW MaVue AS 
     SELECT row_number() OVER () AS id_unique,
        TableA.id_A,
        TableA.num_A,
        TableB.num_B
     
       FROM TableA
       LEFT JOIN TableB ON TableA.id_A = TableB.A_id;
     
    ALTER TABLE MaVue
      OWNER TO sig;
    GRANT ALL ON TABLE MaVue TO sig;
     
     
    CREATE TRIGGER vue_trg
      INSTEAD OF INSERT OR UPDATE OR DELETE
      ON MaVue
      FOR EACH ROW
      EXECUTE PROCEDURE MonTrigger();

    Et voici mon 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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    CREATE OR REPLACE FUNCTION MonTrigger()
      RETURNS trigger AS
    $BODY$
    DECLARE new_id_A BIGINT;
    BEGIN
        IF (TG_OP = 'INSERT') THEN
    	SELECT nextval('seq_A')INTO new_id_A;
     
            INSERT INTO TableA (geom, num_A) 
                   VALUES (NEW.geom, NEW.num_A);
            RETURN NEW;
     
    	INSERT INTO TableB (A_id, num_B) 
                   VALUES (DEFAULT, NEW.num_B);
            RETURN NEW;
     
     
        ELSIF (TG_OP = 'UPDATE') THEN
     
           	UPDATE TableA SET (geom, num_A) 
     
                     = (NEW.geom, NEW.num_A)
            WHERE id_A = NEW.id_A;
     
    	UPDATE TableB SET (num_B) 
     
                     = (NEW.num_B)
            WHERE id_A = NEW.id_A;
     
     
            RETURN NEW;
     
         ELSIF (TG_OP = 'DELETE') THEN
            DELETE FROM TableA WHERE id_A = OLD.id_A;
    	DELETE FROM TableB WHERE A_id = OLD.id_A;
     
       	RETURN NULL;
     
     END IF;
    END;
    $BODY$
      LANGUAGE plpgsql VOLATILE
      COST 100;
    ALTER FUNCTION MonTrigger()
      OWNER TO sig;
    En l'état quand je saisis dans ma vue, les enregistrements vont remplir uniquement ma TableA et pas la TableB....

    Quelqu'un peut-il m'aider?

  2. #2
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 018
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 018
    Points : 23 710
    Points
    23 710
    Par défaut
    Bonjour,

    Peut-être parce que vous avez mis deux fois RETURN NEW; dans la partie INSERT...
    Rédacteur / Modérateur SGBD et R
    Mes tutoriels et la FAQ MySQL

    ----------------------------------------------------
    Pensez aux balises code et au tag
    Une réponse vous a plu ? N'hésitez pas à y mettre un
    Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça

  3. #3
    Membre à l'essai
    Femme Profil pro
    Géomaticienne
    Inscrit en
    Juillet 2018
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Géomaticienne
    Secteur : Service public

    Informations forums :
    Inscription : Juillet 2018
    Messages : 18
    Points : 11
    Points
    11
    Par défaut
    Bonjour ced,

    je viens de re-tester en enlevant un RETURN; j'ai donc ceci maintenant dans mon 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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     CREATE OR REPLACE FUNCTION MonTrigger()
      RETURNS trigger AS
    $BODY$
    DECLARE new_id_A BIGINT;
    BEGIN
        IF (TG_OP = 'INSERT') THEN
    	SELECT nextval('seq_A')INTO new_id_A;
     
            INSERT INTO TableA (geom, num_A) 
                   VALUES (NEW.geom, NEW.num_A);
     
     
    	INSERT INTO TableB (A_id, num_B) 
                   VALUES (DEFAULT, NEW.num_B);
            RETURN NEW;
     
     
        ELSIF (TG_OP = 'UPDATE') THEN
     
           	UPDATE TableA SET (geom, num_A) 
     
                     = (NEW.geom, NEW.num_A)
            WHERE id_A = NEW.id_A;
     
    	UPDATE TableB SET (num_B) 
     
                     = (NEW.num_B)
            WHERE id_A = NEW.id_A;
     
     
            RETURN NEW;
     
         ELSIF (TG_OP = 'DELETE') THEN
            DELETE FROM TableA WHERE id_A = OLD.id_A;
    	DELETE FROM TableB WHERE A_id = OLD.id_A;
     
       	RETURN NULL;
     
     END IF;
    END;
    $BODY$
      LANGUAGE plpgsql VOLATILE
      COST 100;
    ALTER FUNCTION MonTrigger()
      OWNER TO sig;
    j'ai relancé ma Vue et j'obtiens le message d'erreur suivant :

    ERROR: record "new" has no field "new_id_A"
    CONTEXT: SQL statement "INSERT INTO MaTableA (id_A, geom, num_A)
    VALUES (NEW.new_id_A, NEW.geom, NEW.num_A)"
    PL/pgSQL function MonTrigger() line 6 at SQL statement

    ********** Erreur **********

    ERROR: record "new" has no field "new_id_A"
    État SQL :42703
    Contexte : SQL statement "INSERT INTO MaTableA (id_A, geom, num_A)
    VALUES (NEW.new_id_A, NEW.geom, NEW.num_A)"
    PL/pgSQL function MonTrigger() line 6 at SQL statement

  4. #4
    Membre à l'essai
    Femme Profil pro
    Géomaticienne
    Inscrit en
    Juillet 2018
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Géomaticienne
    Secteur : Service public

    Informations forums :
    Inscription : Juillet 2018
    Messages : 18
    Points : 11
    Points
    11
    Par défaut
    J'ai essayé en enlevant la DECLARE new_id_A, mais j'ai fait cela dans le but de pouvoir permettre la saisis automatique de mes clés secondaires dans ma tableB....
    Mais ça ne marche pas non plus

  5. #5
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 821
    Points
    30 821
    Par défaut
    C'est bizarre, le code des lignes qui retournent une erreur d'exécution n'apparait pas dans le script de la fonction...
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  6. #6
    Membre à l'essai
    Femme Profil pro
    Géomaticienne
    Inscrit en
    Juillet 2018
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Géomaticienne
    Secteur : Service public

    Informations forums :
    Inscription : Juillet 2018
    Messages : 18
    Points : 11
    Points
    11
    Par défaut
    Nouveau 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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     CREATE OR REPLACE FUNCTION MonTrigger()
      RETURNS trigger AS
    $BODY$
    DECLARE new_id_A BIGINT;
    BEGIN
        IF (TG_OP = 'INSERT') THEN
    	SELECT nextval('seq_A')INTO new_id_A;
     
            INSERT INTO TableA (id_A, geom, num_A) 
                   VALUES (NEW.new_id_A, NEW.geom, NEW.num_A);
     
     
    	INSERT INTO TableB (A_id, num_B) 
                   VALUES (DEFAULT, NEW.num_B);
            RETURN NEW;
     
     
        ELSIF (TG_OP = 'UPDATE') THEN
     
           	UPDATE TableA SET (geom, num_A) 
     
                     = (NEW.geom, NEW.num_A)
            WHERE id_A = NEW.id_A;
     
    	UPDATE TableB SET (num_B) 
     
                     = (NEW.num_B)
            WHERE id_A = NEW.id_A;
     
     
            RETURN NEW;
     
         ELSIF (TG_OP = 'DELETE') THEN
            DELETE FROM TableA WHERE id_A = OLD.id_A;
    	DELETE FROM TableB WHERE A_id = OLD.id_A;
     
       	RETURN NULL;
     
     END IF;
    END;
    $BODY$
      LANGUAGE plpgsql VOLATILE
      COST 100;
    ALTER FUNCTION MonTrigger()
      OWNER TO sig;
    Et voici mon erreur retournée :

    ERROR: record "new" has no field "new_id_A"
    CONTEXT: SQL statement "INSERT INTO MaTableA (id_A, geom, num_A)
    VALUES (NEW.new_id_A, NEW.geom, NEW.num_A)"
    PL/pgSQL function MonTrigger() line 6 at SQL statement

    ********** Erreur **********

    ERROR: record "new" has no field "new_id_A"
    État SQL :42703
    Contexte : SQL statement "INSERT INTO MaTableA (id_A, geom, num_A)
    VALUES (NEW.new_id_A, NEW.geom, NEW.num_A)"
    PL/pgSQL function MonTrigger() line 6 at SQL statement

  7. #7
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 821
    Points
    30 821
    Par défaut
    La pseudo table NEW possède-telle une colonne nommée new_id_A ?
    Si tu veux faire référence à la variable new_id_A déclarée quelques lignes plus tôt, il ne faut pas la préfixer avec NEW..
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  8. #8
    Membre à l'essai
    Femme Profil pro
    Géomaticienne
    Inscrit en
    Juillet 2018
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Géomaticienne
    Secteur : Service public

    Informations forums :
    Inscription : Juillet 2018
    Messages : 18
    Points : 11
    Points
    11
    Par défaut
    Je viens de faire qq changements, voici mon nouveau Trigger ou dans l'INSERT j'ai remplacé NEW.id_A par DEFAULT

    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
    37
    38
    39
    40
    41
    42
    43
    44
    CREATE OR REPLACE FUNCTION MonTrigger()
      RETURNS trigger AS
    $BODY$
    DECLARE id_A BIGINT;
    BEGIN
        IF (TG_OP = 'INSERT') THEN SELECT nextval('sep_A') INTO id_A;
    		
            INSERT INTO MaTableA (id_A, geom, num_A) 
                   VALUES (DEFAULT, NEW.geom, NEW.num_A);
          
    
    	INSERT INTO MaTableB (A_id, num_B) 
                   VALUES (DEFAULT, NEW.num_B);
         
            RETURN NEW;
            
        ELSIF (TG_OP = 'UPDATE') THEN
               
           	UPDATE MaTableA SET (geom, num_A) 
      
                     = (NEW.geom, NEW.num_A)
            WHERE id_A = NEW.id_A;
    
    	UPDATE MaTableB SET (num_B) 
      
                     = (NEW.num_B)
            WHERE id_A = NEW.id_A;
    
    	
            RETURN NEW;
        
         ELSIF (TG_OP = 'DELETE') THEN
            DELETE FROM MaTableA WHERE id_A = OLD.id_A;
    	DELETE FROM MaTableB WHERE A_id = OLD.id_A;
    	
       	RETURN NULL;
    	
     END IF;
    END;
    $BODY$
      LANGUAGE plpgsql VOLATILE
      COST 100;
    ALTER FUNCTION MonTrigger()
      OWNER TO sig;
    Et dans ma Vue j'ai enlevé le champ id_A, et j'ai maintenant 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
    20
    CREATE OR REPLACE VIEW MaVue AS 
     SELECT row_number() OVER () AS id_unique,
       MaTableA.geom,
       MaTableA.num_A,
       MaTableB.num_B
     
       FROM MaTableA
       LEFT JOIN MaTableB ON MaTableA.id_A = MaTableB.A_id;
     
     
    ALTER TABLE MaVue
      OWNER TO sig;
    GRANT ALL ON TABLE MaVue TO sig;
     
     
    CREATE TRIGGER vue_trg
      INSTEAD OF INSERT OR UPDATE OR DELETE
      ON MaVue
      FOR EACH ROW
      EXECUTE PROCEDURE MonTrigger();
    Maintenant les champs dans ma TableA et TableB se remplissent sauf ma clé secondaire dans ma TableB

  9. #9
    Membre à l'essai
    Femme Profil pro
    Géomaticienne
    Inscrit en
    Juillet 2018
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Géomaticienne
    Secteur : Service public

    Informations forums :
    Inscription : Juillet 2018
    Messages : 18
    Points : 11
    Points
    11
    Par défaut
    Je viens de résoudre mon soucis en écrivant mon Trigger comme ceci pour la partie UPDATE ET DELETE :

    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
    ELSIF (TG_OP = 'UPDATE') THEN
     
           	UPDATE TableA SET (geom, num_A) 
     
                     = (NEW.geom, NEW.num_A) 
            WHERE TableA.id_A = NEW.id_A ;
     
     
    	UPDATE TableB SET (num_B) 
     
                     = (NEW.num_B)
            WHERE TableB.A_id = NEW.id_A ;
     
     
            RETURN NEW;
     
         ELSIF (TG_OP = 'DELETE') THEN
            DELETE FROM TableA WHERE TableA.id_A = OLD.id_A;
    	DELETE FROM TableB WHERE TableB.A_id = OLD.id_A;
     
       	RETURN NULL;
     
     END IF;
    END;
    $BODY$
    Merci à tous pour votre aide

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

Discussions similaires

  1. trigger sur une vue sur sqlserver 2005
    Par thor76160 dans le forum MS SQL Server
    Réponses: 8
    Dernier message: 07/03/2009, 11h41
  2. Réponses: 5
    Dernier message: 12/02/2009, 09h27
  3. [MSSQL05] Archivage de données, trigger sur une vue
    Par tamiii dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 01/07/2008, 13h54
  4. TRIGGER sur une vue
    Par islamune9 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 18/09/2007, 17h32
  5. Boucler sur une table pour renommer des valeurs
    Par webwhisky dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 03/01/2006, 14h19

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