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).

#1 Re : Général » fonction de mise à jour automatique (trigger) » 07/08/2015 15:19:14

J'imagine que la table metadonnees a une clef primaire avec sources_donnees, libel_colonne ? Est-ce que sources_donnees est un nom de table ?
Si c'est bien ca, il faut faire une jointure adresse --> metadonnees .
Dans un trigger , le nom de la table est dans TG_TABLE_NAME .
Pour savoir quels sont les champs modifiés, il faut comparer OLD et NEW;
Exemple :

IF (NEW.num_voie != OLD.num_voie) THEN
    UPDATE metadonnees  SET date_maj = now() WHERE (sources_donnees=TG_TABLE_NAME AND libel_colonne='num_voie')                
END IF;
... idem pour tous les champs...
RETURN NEW

Courage ! PostgreSQL est un super outil, on peut tout faire. Essayez de bien structurer vos questions, on a parfois du mal a vous comprendre.
Alex

#2 Re : Général » fonction de mise à jour automatique (trigger) » 06/08/2015 16:16:15

Bonjour,
je ne suis pas certain d'avoir bien compris ce que vous voulez faire . Avez-vous 2 tables bas_adresse... et base_adresse... ou est-ce une faute de frappe ?
En tout cas, pour mettre la date de derniere mise à jour il faut utiliser le signe d'affectation := et non pas le comparateur = .
Pour l'update, si vous ne mettez pas de clause where toute la table sera mise à jour. NEW.now() ne veut rien dire, utilisez simplement now(), il ne change pas pendant la durée de la transaction.

Un exemple simple qui marche :

CREATE FUNCTION stamp_update() RETURNS trigger
    LANGUAGE plpgsql
    AS $$DECLARE
nom_base varchar;

BEGIN

       SELECT INTO nom_base current_database();

        NEW.dat_tran := current_timestamp;

        NEW.user_db_tran := nom_base;

        RETURN NEW;

    END;$$;

CREATE TRIGGER stamp_update BEFORE INSERT ON adresse FOR EACH ROW EXECUTE PROCEDURE stamp_update();

Je ne sais pas à quoi correspond votre table de métadonnées, mais dans un projet précédent j'avais une table d'archivage par table "utilisateur" de toutes les opérations effectuées alimentée automatiquement de cette façon (exemple tables adresse et adresse_log):

CREATE FUNCTION log_adresse() RETURNS trigger
    LANGUAGE plpgsql
    AS $$BEGIN

IF (TG_OP = 'DELETE' )  THEN

        INSERT INTO adresse_log SELECT 'D', now(), OLD.*;

        RETURN OLD;

ELSEIF (TG_OP = 'UPDATE' ) THEN 

        INSERT INTO adresse_log SELECT 'U', now(), NEW.*;

        RETURN NEW;

ELSEIF (TG_OP = 'INSERT' ) THEN 

        INSERT INTO adresse_log SELECT 'I', now(), NEW.*;

        RETURN NEW;

END IF;

RETURN NULL;     END;$$;

CREATE TRIGGER xlog_adresse BEFORE INSERT OR DELETE OR UPDATE ON adresse FOR EACH ROW EXECUTE PROCEDURE log_adresse();

Les 2 tables ont la meme structure , a part un champ code transaction et un timestamp en plus pour la table log.

J'espère que ces exemples vous aideront.

Alex

#3 Re : Général » Mise à jour structure d'une base sur le modèle d'une autre » 19/01/2015 15:04:13

Bonjour,
il y a 3 ans j’ai utilisé avec succès apgdiff : Another PostGreSQL Diff Tool  .
Il permet de comparer 2 exports et générer un script pour rendre la structure des 2 bases identiques.
Je ne sais pas s’il est toujours d’actualité, mais ça vaut sûrement la peine d’y jeter un oeil.

Alex Leguevaques

#5 Re : PSQL » trigger » 05/04/2014 14:59:02

Bonjour, vous pouvez aller voir cette discussion pour démarrer.

Alex

#6 Re : Installation » problème de droit pour une connexion à distance » 07/02/2014 10:45:32

Oups ! Il s'agit de modifier le fichier postgresql.conf !
Désolé pour le bruit.

Alex

#7 Re : Installation » problème de droit pour une connexion à distance » 07/02/2014 10:43:07

Dans pg_hba.conf , mettre

listen_addresses = '*'

pour accepter toutes les connections ou

listen_addresses='localhost,192.168.0.1'

par exemple pour les connections locales + l'adresse Ip 192.168.0.1 .


Alex

#8 Re : Site PostgreSQL.fr » Informations Choix PostgreSQL » 05/02/2014 22:41:23

En ce qui concerne les requêtes récursives, Pg les connait depuis au moins la 8.4 .
Voir dans ce forum ce thread et la documentation sur le create view ou la documentation sur les CTE .

#10 Re : Site PostgreSQL.fr » Informations Choix PostgreSQL » 04/02/2014 14:09:44

Bonjour,
le "problème de lenteur" est une idée reçue datant de Pg 7.4 (qui date de 2003 !) .
Il est vrai que MySQL a été conçu en privilégiant les performances plutôt que la fiabilité, alors que Pg a fait le choix inverse.
Mais depuis plusieurs années, d'énormes progrès ont été faits des 2 côtés pour gommer les défauts.
L'évolution de Pg me semble plus rapide et allant dans le bon sens, de plus on peut discuter du fait que MySQL soit vraiment open source,
puisque c'est la propriété d'Oracle, alors que Pg est développé par la communauté .
Pg semble être en plein décollage, avec des fonctionnalités innovantes à chaque release, tous les ans depuis 3 ou 4 ans, voir cet article.
Une recherche sur Google vous permettra de trouver des comparatifs qui vous éclaireront.
Pour ce qui est du développement Web , lisez le témoignage de Christophe Legendre, DBA de "leboncoin.fr".

Alex

#11 Re : Général » effectuer des opérations (*, / ,..) entre des données d'une meme table » 30/01/2014 14:08:09

Le mail dans mon profil était obsolète, je l'ai corrigé.
Bonne continuation

Alex

#12 Re : Général » effectuer des opérations (*, / ,..) entre des données d'une meme table » 29/01/2014 23:54:50

La déclaration de curseur ne sert à rien . Pour Java, je suis totalement incompétent sur le sujet. Essayez dans Forum PostgreSQL.fr et Java .
Si vous voulez faire des triggers plus compliqués, je peux vous donner des tonnes d'exemples, de quelques dizaines à quelques centaines de lignes.
Plutôt par MP, pour ne pas surcharger inutilement le forum.
Alex

#13 Re : Général » effectuer des opérations (*, / ,..) entre des données d'une meme table » 29/01/2014 00:01:24

Je me suis mal fait comprendre.
Soit une table "matable" avec un champ id de type integer et un champ alp de type varchar(10).
Si vous avez un trigger "before update" de la table "matable" qui appelle la fonction "mon-calcul", l'enchaînement est le suivant :

1) Un client (appli, psql...) exécute

UPDATE matable set alp = "a" WHERE id = 1;

2) PostgreSQL déclenche le trigger qui active la fonction mon-calcul.
Cette fonction prend la main juste avant que l'update soit réalisé.
Admettons que la fonction mon-calcul contienne une ligne :

IF (NEW.alp = "a") THEN
  NEW.alp := "x"
END IF;

3) Cette ligne est suffisante pour que la ligne soit stockée avec les valeurs 1 et "x" .
Il ne faut surtout pas faire d'update de matable dans la fonction, car le trigger sera déclenché qui activera la fonction avec l'update qui...etc...
Pour résumer, dans une fonction trigger before update, vous êtes en train de faire l'update, et vous pouvez intervenir "au vol" pour faire les contrôles que vous voulez. Dans votre fonction trigger, il ne devrait y avoir que :

-- Function: calc_surfaceutile()
-- DROP FUNCTION calc_surfaceutile();
CREATE OR REPLACE FUNCTION calc_surfaceutile()
  RETURNS trigger AS
$BODY$BEGIN    

    BEGIN
    IF (NEW.art_vch_surface IS NOT NULL) THEN
        NEW.art_dec_surfaceutile := (NEW.art_dec_coefchutearticlepopup * NEW.art_vch_surface);
    END IF;
    RETURN NEW;
END;

$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION calc_surfaceutile()
  OWNER TO postgres;

Le trigger devrait ressembler à ça :

DROP TRIGGER calc_surfaceutile ON article;
  CREATE TRIGGER calc_surfaceutile
  BEFORE INSERT OR UPDATE
  ON article
  FOR EACH ROW
  EXECUTE PROCEDURE calc_surfaceutile();

Lorsque ce sera en place, tous les insert et update mettront à jour la colonne art_dec_surfaceutile de la table article.
Il y a la mise à jour des lignes existantes à faire, soit au préalable (avant de créer le trigger), soit en ayant désactivé le trigger le temps de l'update , soit en faisant une fausse modif pour déclencher le trigger sur toutes les lignes.

#14 Re : Général » effectuer des opérations (*, / ,..) entre des données d'une meme table » 27/01/2014 22:58:15

J'utilise phpPgAdmin et psql et ne connais pas PgAdmin, je ne peux rien dire là dessus.
Pour le reste, lorsqu'une fonction est appelée dans un trigger, certaines variables sont créées et valorisées automatiquement par PostgresSQL :
NEW : contient la ligne qui va être enregistrée  (valable en UPDATE ou INSERT uniquement). On accède aux champs avec NEW.champ1, NEW.champ2...etc... Si on modifie un champ et que le trigger se termine bien, cette nouvelle valeur sera stockée.
OLD : la ligne avant les modifs (valable en UPDATE ou DELETE uniquement)
Pour plus d'infos voir Triggers procedures .
La fonction peut être appelée d'autres triggers, on peut même faire une fonction "générique" qui teste le cas INSERT/UPDATE/DELETE et effectue des traitements spécifiques.

Exemple :

IF (TG_OP = 'INSERT') THEN
 NEW.dat_creat := current_timestamp;
 NEW.user_db_creat := current_user;       

ELSEIF (TG_OP = 'UPDATE') THEN
   NEW.dat_tran := current_timestamp;
   NEW.user_db_tran := current_user;
END IF;

Je ne parle que des triggers au niveau ligne, en 9.3 il y a les "event triggers" qui se déclenchent lors des ordres DDL (CREATE TABLE, DROP TABLE...)
mais vous verrez ça plus tard...

#15 Re : Général » effectuer des opérations (*, / ,..) entre des données d'une meme table » 27/01/2014 15:14:28

En relisant votre message, je crois comprendre la confusion que vous faites.
Un trigger (= déclencheur en français) est un évènement que vous pouvez intercepter pour mettre du code .
Exemple ci-dessus pour renseigner base d'origine et date / heure création à chaque insert.
Si, comme je crois avoir compris, vous ajoutez un champ calculé dans votre table, il vous faut faire 2 choses :
1) Un update pour l'existant, par exemple :

 UPDATE matable set colonneresultat_dematable = colonne1_dematable * colonne2_dematable
               WHERE colonne2_dematable IS NOT NULL;

2) Une fonction appelée dans un trigger "before insert or update" qui fera simplement :

CREATE FUNCTION majtot() RETURNS trigger
    LANGUAGE plpgsql
    AS $$
DECLARE
    BEGIN
        IF (colonne2_dematable IS NOT NULL) THEN
NEW.colonneresultat_dematable := NEW.colonne1_dematable * New.colonne2_de ma table;
END IF;
        RETURN NEW;
    END;
$$;

ALTER FUNCTION public.majtot() OWNER TO toto;

Notez le ":=" pour l'affectation et le ";" en fin de ligne .

La création du trigger :

CREATE TRIGGER trg_majtot
    BEFORE INSERT OR UPDATE ON matable
    FOR EACH ROW
    EXECUTE PROCEDURE majtot();

Avec ça, toutes les modifs et créations calculeront le nouveau champ.

#16 Re : Général » effectuer des opérations (*, / ,..) entre des données d'une meme table » 27/01/2014 14:40:13

Bonjour,
voici un exemple de fonction appelée dans un trigger :

CREATE FUNCTION stamp_insert() RETURNS trigger
    LANGUAGE plpgsql
    AS $$
DECLARE
nom_base varchar;
    BEGIN
        SELECT INTO nom_base current_database();
        NEW.dat_creat := current_timestamp;
        NEW.user_db_creat := nom_base;
        RETURN NEW;
    END;
$$;

ALTER FUNCTION public.stamp_insert() OWNER TO toto;

et le trigger :

CREATE TRIGGER stamp_insert
    BEFORE INSERT ON matable
    FOR EACH ROW
    EXECUTE PROCEDURE stamp_insert();

Espérant vous aider

Alex

#17 Re : PgAdmin3 » Enregistrer mot de passe fonctionne pas à connexion serveur » 09/11/2013 20:16:26

Bonjour,
pour le dernier message, il faut aller dans Préférences systèmes ==> Sécurité et confidentialité et débloquer PgAdmin (pour OS X 10.9) ou
autoriser les applications téléchargées de n'importe où (< 10.9) , installer PgAdmin , et remettre "Mac App Store et développeurs identifiés" (je vous le conseille, la sécurité est à ce prix) .

Alex

#18 Re : Général » [RESOLU] Type booléen et libellés affichés » 09/08/2013 20:05:14

Bonjour,
vous pouvez utiliser un CASE :

SELECT a,
       CASE WHEN a IS TRUE THEN 'TRUE'
            WHEN a IS FALSE THEN 'FALSE'
            ELSE 'UNKNOWN'
       END
    FROM toto;

La doc est ici


Alex

#19 Re : Sécurité » cacher son mot de passe » 18/06/2013 21:56:43

Je crois que vous n'avez pas créé l'extension pgcrypto, comme indiqué par rjuju . Exemple :

$ psql
psql (9.2.4)
Saisissez « help » pour l'aide.

conclavi_test=# select encrypt('azerty','fooz','bf');
ERREUR:  la fonction encrypt(unknown, unknown, unknown) n'existe pas
LIGNE 1 : select encrypt('azerty','fooz','bf');
                 ^
ASTUCE : Aucune fonction ne correspond au nom donné et aux types d'arguments.
Vous devez ajouter des conversions explicites de type.
conclavi_test=# \dx
                Liste des extensions installées
   Nom   | Version |   Schéma   |         Description          
---------+---------+------------+------------------------------
 plpgsql | 1.0     | pg_catalog | PL/pgSQL procedural language
(1 ligne)

conclavi_test=# create extension pgcrypto;
CREATE EXTENSION
conclavi_test=# \dx
                Liste des extensions installées
   Nom    | Version |   Schéma   |         Description          
----------+---------+------------+------------------------------
 pgcrypto | 1.0     | public     | cryptographic functions
 plpgsql  | 1.0     | pg_catalog | PL/pgSQL procedural language
(2 lignes)

conclavi_test=# select encrypt('azerty','fooz','bf');
      encrypt       
--------------------
 \x888475ea29dbb241
(1 ligne)

conclavi_test=# 

Alex

#20 Re : PHP » Ecriture de données avec PHP et clés étrangères » 18/06/2013 19:59:33

Bonjour,
un exemple  :

$sql = "insert into licencie(id_licencie,id_identite,qualif_cartet,diplome,discipline)
values(default,$identiter,'$carte_pro','$diplome','$discipline')returning id_licencie";
$result = pg_query($db, $sql);
 if (!$result) {
             die("Erreur SQL: " . pg_last_error());
   }
$ligne = pg_fetch_row($result);
$id_licencie = $ligne[0];

Alex

#21 Re : Sécurité » cacher son mot de passe » 17/06/2013 21:48:47

Bonjour,
j'ai l'impression que les quotes autour de mot_de_passe sont en trop :

select id, decrypt(mot_de_passe,'1234','aes') from utilisateur where ...

L'exemple donné dans la doc parle de : encrypt(data, 'fooz', 'bf')

La doc est là


Alex

#22 Re : Général » [résolu] reindex a partir de 1 » 12/06/2013 22:03:52

Bonjour,
Si vous voulez réinitialiser une séquence , la doc est là : Fonctions de manipulation de séquences .

Sinon, pourriez-vous préciser votre question ?

Alex

#23 Re : Général » PostgreSQL 9.4 / AXLE » 04/05/2013 18:30:37

Pg 9.4 risque d'avoir quelques arguments supplémentaires pour séduire les clients Oracle big_smile

#24 Général » PostgreSQL 9.4 / AXLE » 03/05/2013 14:52:15

MitsuTomoe
Réponses : 2

Bonjour,
j'ai lu avec le plus grand intérêt l'article AXLE improves analytics on Big Data .
Bien que n'étant pas directement concerné, cette future extension des possibilités de PostgreSQL ne peut que nous conforter dans notre choix.
Néanmoins, je me pose quelques questions sur l'interprétation de :

First deliverables from the project will be submitted to PostgreSQL version 9.4, available in 2014 and will continue in later releases.

Est-ce que AXLE sera une extension, comme PostGIS ? Ou PostgreSQL sera-t-il modifié en profondeur ? Et dans ce cas, il faudra un dialogue entre AXLE et la core team de PostgreSQL ?
Quid des arbitrages ? Simple curiosité de ma part .

Alex

Pied de page des forums

Propulsé par FluxBB