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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    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
    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 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loiret (Centre)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 065
    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 averti
    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
    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 averti
    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
    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 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    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 136
    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 averti
    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
    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

+ 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