PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#2 Re : PL/pgSQL » le NEW.* ne quote pas les chaînes de caractères dans un EXECUTE » 16/07/2012 14:13:24

Il n'y a pas moyen de contourner ce comportement pour que le NEW soit interprété comme une commande et que son résultat ne soit pas traduit en chaîne de caractères ?

#3 Re : PL/pgSQL » le NEW.* ne quote pas les chaînes de caractères dans un EXECUTE » 16/07/2012 12:19:46

oui, la création de la fonction s'exécute bien avec ce code :

CREATE OR REPLACE FUNCTION cvae_insert_trigger() RETURNS TRIGGER AS $$
DECLARE
    v_nombre SMALLINT;
    v_annee SMALLINT;
    v_table VARCHAR;
BEGIN
    v_annee := NEW.annee;
    v_table := 'cvae' || v_annee;
   
    SELECT count(*) INTO v_nombre FROM pg_tables WHERE pg_tables.tablename = v_table;
    IF ( v_nombre = 0 ) THEN
        -- Creation de la partition si elle n'existe pas
        EXECUTE 'CREATE TABLE ' || v_table || '( '
        || 'PRIMARY KEY (annee, idcvae), '
        || 'CONSTRAINT ' || v_table || '_annee_check CHECK (annee =  ' || v_annee  || '), '
        || 'CONSTRAINT ' || v_table || '_commune_fkey FOREIGN KEY (codecommunedpt) REFERENCES commune(codecommunedpt), '
        || 'CONSTRAINT ' || v_table || '_sousclasse_fkey FOREIGN KEY (codesousclasse) REFERENCES naf_sous_classe(codesousclasse), '
        || 'CONSTRAINT ' || v_table || '_voie_fkey FOREIGN KEY (codevoie, codecommunedpt) REFERENCES voie(codevoie, codecommunedpt), '
        || 'CONSTRAINT ' || v_table || '_formejuridique_fkey FOREIGN KEY (idformejuridique) REFERENCES forme_juridique(idformejuridique), '
        || 'CONSTRAINT ' || v_table || '_zone_fkey FOREIGN KEY (idzonage, idzone) REFERENCES zone(idzonage, idzone), '
        || 'CONSTRAINT ' || v_table || '_entreprise_fk FOREIGN KEY (siren) REFERENCES entreprise(siren), '
        || 'CONSTRAINT ' || v_table || '_etablissement_fkey FOREIGN KEY (siren, nic) REFERENCES etablissement(siren, nic)) '
        || 'INHERITS (cvae)';
   
        EXECUTE 'CREATE INDEX ifk_' || v_table || '_commune ON ' || v_table || ' (CodeCommuneDpt)';
        EXECUTE 'CREATE INDEX ifk_' || v_table || '_voie ON ' || v_table || ' (CodeVoie, CodeCommuneDpt)';
        EXECUTE 'CREATE INDEX ifk_' || v_table || '_formejuridique ON ' || v_table || ' (IdFormeJuridique)';
        EXECUTE 'CREATE INDEX ifk_' || v_table || '_entreprise ON ' || v_table || ' (SIREN)';
        EXECUTE 'CREATE INDEX ifk_' || v_table || '_etablissement ON ' || v_table || ' (SIREN, NIC)';
        EXECUTE 'CREATE INDEX ifk_' || v_table || '_nafsousclasse ON ' || v_table || ' (CodeSousClasse)';
        EXECUTE 'CREATE INDEX ifk_' || v_table || '_zone ON ' || v_table || ' (IdZonage, IdZone)';
        EXECUTE 'CREATE INDEX i_' || v_table || '_denomination ON ' || v_table || ' (Denomination)';
    END IF;

    EXECUTE 'INSERT INTO ' || v_table || ' VALUES ' || NEW.*;
    RETURN NULL;
END;
$$
LANGUAGE plpgsql;

#4 Re : PL/pgSQL » le NEW.* ne quote pas les chaînes de caractères dans un EXECUTE » 16/07/2012 11:42:47

Merci pour la réponse rapide.

J'ai changé la syntaxe dans la ligne suivante (j'ai enlevé les parenthèses) mais j'ai toujours le problème :
EXECUTE 'INSERT INTO ' || v_table || ' VALUES ' || NEW.*;

ERROR:  syntax error at or near ","
LINE 1: INSERT INTO cvae2012 VALUES (2012,1,123456789,,,,toto,,,,,...
                                                                                      ^
QUERY:  INSERT INTO cvae2012 VALUES (2012,1,123456789,,,,toto,,,,,,,,,,,,,,,,,,,,,,)
CONTEXT:  PL/pgSQL function "cvae_insert_trigger" line 35 at EXECUTE statement

Après la valeur numérique 123456789, je suppose qu'il devrait y avoir ,'' (idem pour la valeur toto qui devrait être 'toto').

#5 PL/pgSQL » le NEW.* ne quote pas les chaînes de caractères dans un EXECUTE » 16/07/2012 10:44:46

leTaz
Réponses : 8

Bonjour à tous.

Je me suis basé sur l'exemple donné dans la doc (postgreSQL 9.1.4) pour créer une table partitionnée avec un trigger. La table est partitionnée sur l'année, la fonction appelée par le trigger crée la table partitionnée si elle n'existe pas et insère l'occurrence dans celle-ci.

Le problème est dans l'instruction : EXECUTE 'INSERT INTO ' || v_table || ' VALUES (' NEW.* ')';
Le NEW.* ne renvoie pas les chaînes de caractères entourées de quotes, ce qui fait planter l'INSERT.

Auriez-vous une solution ? Merci d'avance.

Voici le code :

CREATE OR REPLACE FUNCTION cvae_insert_trigger() RETURNS TRIGGER AS $$
DECLARE
    v_nombre SMALLINT;
    v_annee SMALLINT;
    v_table VARCHAR;
BEGIN
    v_annee := NEW.annee;
    v_table := 'cvae' || v_annee;
   
    SELECT count(*) INTO v_nombre FROM pg_tables WHERE pg_tables.tablename = v_table;
    IF ( v_nombre = 0 ) THEN
        -- Creation de la partition si elle n'existe pas
        EXECUTE 'CREATE TABLE ' || v_table || '( '
        || 'PRIMARY KEY (annee, idcvae), '
        || 'CONSTRAINT ' || v_table || '_annee_check CHECK (annee =  ' || v_annee  || '), '
        || 'CONSTRAINT ' || v_table || '_commune_fkey FOREIGN KEY (codecommunedpt) REFERENCES commune(codecommunedpt), '
        || 'CONSTRAINT ' || v_table || '_sousclasse_fkey FOREIGN KEY (codesousclasse) REFERENCES naf_sous_classe(codesousclasse), '
        || 'CONSTRAINT ' || v_table || '_voie_fkey FOREIGN KEY (codevoie, codecommunedpt) REFERENCES voie(codevoie, codecommunedpt), '
        || 'CONSTRAINT ' || v_table || '_formejuridique_fkey FOREIGN KEY (idformejuridique) REFERENCES forme_juridique(idformejuridique), '
        || 'CONSTRAINT ' || v_table || '_zone_fkey FOREIGN KEY (idzonage, idzone) REFERENCES zone(idzonage, idzone), '
        || 'CONSTRAINT ' || v_table || '_entreprise_fk FOREIGN KEY (siren) REFERENCES entreprise(siren), '
        || 'CONSTRAINT ' || v_table || '_etablissement_fkey FOREIGN KEY (siren, nic) REFERENCES etablissement(siren, nic)) '
        || 'INHERITS (cvae)';
   
        EXECUTE 'CREATE INDEX ifk_' || v_table || '_commune ON ' || v_table || ' (CodeCommuneDpt)';
        EXECUTE 'CREATE INDEX ifk_' || v_table || '_voie ON ' || v_table || ' (CodeVoie, CodeCommuneDpt)';
        EXECUTE 'CREATE INDEX ifk_' || v_table || '_formejuridique ON ' || v_table || ' (IdFormeJuridique)';
        EXECUTE 'CREATE INDEX ifk_' || v_table || '_entreprise ON ' || v_table || ' (SIREN)';
        EXECUTE 'CREATE INDEX ifk_' || v_table || '_etablissement ON ' || v_table || ' (SIREN, NIC)';
        EXECUTE 'CREATE INDEX ifk_' || v_table || '_nafsousclasse ON ' || v_table || ' (CodeSousClasse)';
        EXECUTE 'CREATE INDEX ifk_' || v_table || '_zone ON ' || v_table || ' (IdZonage, IdZone)';
        EXECUTE 'CREATE INDEX i_' || v_table || '_denomination ON ' || v_table || ' (Denomination)';
    END IF;

    EXECUTE 'INSERT INTO ' || v_table || ' VALUES (' NEW.* ')';
    RETURN NULL;
END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER cvae_insert_trigger
    BEFORE INSERT ON cvae
    FOR EACH ROW EXECUTE PROCEDURE cvae_insert_trigger();

Voici l'erreur :
ERROR:  syntax error at or near ","
LINE 1: INSERT INTO cvae2012 VALUES ((2012,1,123456789,,,,toto,,,,...
                                                       ^
QUERY:  INSERT INTO cvae2012 VALUES ((2012,1,123456789,,,,toto,,,,,,,,,,,,,,,,,,,,,,))
CONTEXT:  PL/pgSQL function "cvae_insert_trigger" line 35 at EXECUTE statement

Pied de page des forums

Propulsé par FluxBB