Vous n'êtes pas identifié(e).
Un exemple réel vous aidera probablement. J'ai écrit ce code alors que je découvrais PG, il est donc certainement perfectible,
mais ça fonctionne.
Le trigger :
CREATE TRIGGER agenda_projet BEFORE INSERT OR UPDATE ON client_projet FOR EACH ROW EXECUTE PROCEDURE agenda_projet();
La fonction :
CREATE FUNCTION agenda_projet() RETURNS trigger
LANGUAGE plpgsql
AS $$--
-- A partir de l'insertion ou update dans PROJET, on met à jour les agendas du projet, du licencié, de son équipe, et des acquéreurs concernés.
--
DECLARE
vtypact integer;
vlic record;
vident record;
vdesc varchar;
vlib varchar;
vevent integer;
vtrt integer;
vidlic integer;
videquipe integer;
vmandat record;
vgroupe record;
vmandatvendeur record;
vdatfin date;
vinit varchar;
BEGIN
vtrt := 0;
CASE
WHEN (TG_OP = 'INSERT') THEN
vtrt := 1;
WHEN (TG_OP = 'UPDATE') THEN
vtrt := 2;
END CASE;
SELECT INTO vgroupe * FROM GROUPE_CLIENT WHERE id_groupe=NEW.id_groupe;
IF NOT FOUND THEN
RAISE EXCEPTION 'Aucun acquéreur trouvé pour le projet %',NEW.id_groupe;
RETURN NULL;
END IF;
vidlic := NEW.nego_in;
IF (vidlic IS NULL) THEN
RAISE EXCEPTION 'Aucun licencié trouvé pour le projet %',NEW.id_projet;
RETURN NULL;
END IF;
SELECT INTO vlic * FROM LICENCIE WHERE id_licencie=vidlic;
IF NOT FOUND THEN
RAISE EXCEPTION 'Le licencié % n''existe pas !', vidlic;
RETURN NULL;
END IF;
SELECT INTO videquipe id_equipe FROM LICENCIE_PERIODE WHERE (((id_licencie = vidlic) AND (dat_debut <= current_date)) AND ((dat_fin >= current_date OR dat_fin IS NULL)));
IF NOT FOUND THEN
RAISE EXCEPTION 'L''équipe n''a pas été trouvée pour le licencié %',vidlic;
RETURN NULL;
END IF;
SELECT INTO vident * FROM IDENTITE where id_identite=vlic.id_identite;
IF NOT FOUND THEN
RAISE EXCEPTION 'Pas d''identité pour le licencié % !', vidlic;
RETURN NULL;
END IF;
CASE
WHEN (vtrt = 1) THEN
IF (NEW.mandat_rech IS TRUE) THEN
vlib := 'Mandat de recherche ';
ELSE
vlib := 'Mandat simple ';
END IF;
vdesc:=vlib||'no. '||NEW.id_projet;
WHEN (vtrt = 2) THEN
IF (NEW.typ_etat_projet != OLD.typ_etat_projet) THEN
SELECT INTO vlib lib_long FROM LISTE_CHOIX WHERE (cd_lang = 'fr' AND no_liste=10 AND no_val=NEW.typ_etat_projet);
vdesc:= 'projet '||NEW.id_projet||' '||vlib;
ELSE
RETURN NEW;
END IF;
END CASE;
IF (NEW.dat_lim IS NULL) THEN
vdatfin := NEW.dat_projet + interval '1 year';
ELSE
vdatfin := NEW.dat_lim;
END IF;
vtypact := 19;
INSERT INTO AGENDA VALUES(default,1,vtypact,vdesc,NEW.dat_projet,vdatfin) RETURNING currval('agenda_id_event_seq') into vevent;
RAISE NOTICE 'Création de l''évènement % dans l''agenda',vevent;
INSERT INTO CLIENT_PROJET_AGENDA VALUES(NEW.id_projet,vevent);
RAISE NOTICE 'Création de l''évènement % dans l''agenda du client % projet %',vevent,NEW.id_groupe,NEW.id_projet;
INSERT INTO LICENCIE_AGENDA VALUES(vidlic,vevent);
RAISE NOTICE 'Création de l''évènement % dans l''agenda du licencié %',vevent,vidlic;
INSERT INTO EQUIPE_AGENDA VALUES(videquipe,vevent);
RAISE NOTICE 'Création de l''évènement % dans l''agenda de l''équipe %',vevent,videquipe;
RETURN NEW;
END;$$;
ALTER FUNCTION public.agenda_projet() OWNER TO conclavi;
Extrait d'une fonction qui fait ça :
totdiff integer;
lstbien integer[];
vidbien integer;
vidbientest integer;
...
totdiff:=totdiff+1;
lstbien[totdiff] := vidbien;
...
IF (lstbien IS NOT NULL) THEN
FOREACH vidbientest IN ARRAY lstbien LOOP
...
END LOOP;
END IF;
C'est ce que vous cherchez ? Je précise que je suis en 9.2, la syntaxe FOREACH... IN ARRAY est
valable à partir de la 9.1, voir FOREACH IN ARRAY en 9.1
Avant, il faut utiliser unnest (exemple tiré du lien ci-dessus) :
FOR t IN SELECT unnest( in_array ) LOOP
raise notice 't: %', t;
END loop;
Alex
Pour ce qui est de la conformité à la norme SQL, PG est plutôt conforme à SQL:2011 .
Extrait de la documentation :
PostgreSQL supports most of the major features of SQL:2011. Out of 179 mandatory features required for full Core conformance, PostgreSQL conforms to at least 160.
La richesse des types de données de PG n'est pas mise en avant.
Par exemple, je suis en train d'évaluer l'utilisation des types intervalle dans notre projet,
et il semble ne pas y avoir de type booléen dans SQL Server 2012.
Je débute en PG, mais on peut faire des transactions DDL :
conclavi_test=# begin;
BEGIN
conclavi_test=# create table a (x integer);
CREATE TABLE
conclavi_test=# rollback;
ROLLBACK
conclavi_test=# \dS a
Aucune relation nommée « a » n'a été trouvée.
conclavi_test=# begin;
BEGIN
conclavi_test=# \dS a
Table « public.a »
Colonne | Type | Modificateurs
---------+---------+---------------
x | integer |
conclavi_test=# drop table a;
DROP TABLE
conclavi_test=# rollback;
ROLLBACK
conclavi_test=# \dS a
Table « public.a »
Colonne | Type | Modificateurs
---------+---------+---------------
x | integer |
Du coup, j'ai des doutes sur le reste...
Encore plus simple : "show hba_file" dans psql .
Vous pouvez écrire :
SELECT INTO mavar ana_decimal FROM tbl_analyse_ana WHERE ana_id = crit;
Alex
Cliquez sur PostgreSQL dans la fenêtre de gauche, puis sur "Comptes" à droite.
Là, vous verrez "Modifier le mot de passe" .
Alex
J'ai approfondi la question, et je crois maintenant qu'une meilleure solution serait de refaire l'interface
avec un framework PHP type Symfony, pour avoir un code propre et pas trop verbeux.
J'ai lu aussi des articles sur Pomm, qui peut être utilisé avec Symfony et permet de faire du mapping PG <==> Php,
si j'ai bien compris. Si vous avez des infos sur ce type de solution, je suis preneur.
Merci
J'ai certainement une mauvaise compréhension du fonctionnement d'un CMS.
Dans les outils que j'utilisais auparavant, je décrivais le modèle (entités/relations),
puis développais mes formulaires, qui héritaient du modèle.
Le reverse engineering était aussi possible, i.e. recréer le modèle à partir d'une base existante.
J'imaginais donc au pire devoir décrire toutes les tables / relations .
Me gourè-je complètement ?
P.S. : il s'agit de ventes immobilières
Je suis nouveau sur PostgreSQL (1 an), mais j'ai lu plusieurs articles de Frédéric Brouard.
A chaque fois, ça me semble juste techniquement et bien documenté, mais toujours biaisé en faveur de SQL Server
et d'Oracle. Le ton général semble être destiné à faire naitre la polémique, plutôt qu'à ouvrir un dialogue constructif.
De mon côté, j'ai connu RDB (sous OpenVMS) et Oracle (divers U*x) il y a quelques années (jusqu'en 2004) .
Dans Pg, je trouve des fonctionnalités avancées que je ne connaissais pas (fonctions window, data type interval, recherche textuelle...).
Bémol : c'est peut-être dû à l'ancienneté des versions d'autres SGBD que j'ai pratiqués, ou au manque de profondeur de mes compétences.
Mais ce qui me séduit surtout dans Pg, au delà des comparatifs difficilement objectifs, c'est le dynamisme de la communauté,
qui conduit à une rapide progression du produit, et un esprit de solidarité et de partage, toujours appréciable.
Oui, refaire l'interface du site mais garder la base PG . La plupart des CMS utilisent MySQL,
mais Drupal peut fonctionner avec PG . Ca vous semble impossible à faire ?
Bonjour à tous,
nous avons un site développé en PHP/JavaScript/Html avec une base en pg 9.2 (server Ubuntu 12.10) .
La partie pg fonctionne très bien (procédures stockées, triggers...), mais la partie présentation a été
très mal faite. Après moultes recherches, nous voudrions la refaire avec Drupal 8/Symfony.
Avez-vous l'expérience de Drupal avec PG ? Quels sont les pièges à éviter ?
Drupal 8 n'étant pas encore sorti, vaut-il mieux prendre un développeur connaissant bien la V7,
ou qqn ne connaissant pas Drupal du tout ?
Alex
Un exemple sera certainement plus parlant :
DATE=$(date +%Y-%m-%d)
TIME=$(date +%T)
rm -f /var/lib/postgresql/diff_ann.ok
rm -f /var/lib/postgresql/1131422.xml
rm -f /var/lib/postgresql/1131422.zip
psql << EOF
select diff_annonces(1,1,1000);
copy (select id_envoi from diffusion_envoi where dat_envoi is null order by id_envoi limit 1) to '/var/lib/postgresql/diff_ann.ok';
EOF
id=`head -1 /var/lib/postgresql/diff_ann.ok`
if [ -z "$id" ]
then
echo "Aucun fichier à envoyer"
else
echo "Traitement envoi $id"
psql << EOF
copy (select fichier_contenu from diffusion_envoi where id_envoi = $id) to '/var/lib/postgresql/1131422.xml' csv;
update diffusion_envoi set dat_envoi='$DATE $TIME' WHERE id_envoi = $id;
EOF
sed --in-place -e 's/\"\"/\"/g' 1131422.xml
sed --in-place -e 's/\"<?xml/<?xml/g' 1131422.xml
sed --in-place -e 's/"$//g' 1131422.xml
zip -r 1131422.zip 1131422.xml
ftp -in <<THEEND
open xxxx
user xxx xxx
put 1131422.zip
close
bye
THEEND
msg=" $DATE $TIME Envoi no. $id effectué"
echo $msg | mail -s "Multi-diffusion" -t xxx@xx.fr -t -a From:no-reply@xx.xx
fi
diff_annonces est une fonction pl/PgSQL . Le shell est lancé dans le cron .
Alex
Je ne connaissais pas non plus, mais j'ai trouvé cette fonction dans la doc :
dow
Le jour de la semaine du dimanche (0) au samedi (6).SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40');
Résultat : 5
Alex
J'ai présumé (un peu vite) que SAT, CName et VersC ne pouvaient pas être à NULL.
S'ils peuvent être vides, il faut utiliser UNIQUE et non PRIMARY KEY :
create table ClassVersion (
CName text,
VersC integer,
SAT date,
EAT date,
UNIQUE (SAT, CName,VersC));
Pour plus de clarté, on peut nommer la contrainte :
create table ClassVersion (
CName text,
VersC integer,
SAT date,
EAT date);
ALTER TABLE ONLY ClassVersion ADD CONSTRAINT ma_clef_unique UNIQUE (SAT, CName,VersC);
Tout est très bien expliqué dans la doc , que je vous encourage à lire.
create table ClassVersion (
CName text,
VersC integer,
SAT date,
EAT date,
PRIMARY KEY (SAT, CName,VersC));
Pour plus de détails : http://www.postgresql.org/docs/9.2/stat … aints.html
Alex
Bonjour,
si je comprend bien votre colonne Table_adrs contient l'adresse sous forme non structurée, par exemple "10 rue des Alouettes 75006 PARIS" ?
Dans ce cas, vous ne pourrez jamais faire de recherche exacte. Comment distinguer "12 rue de Paris 11100 NARBONNE" de "1 rue de la Paix 75009 PARIS" ?
Si la saisie a été standardisée, vous pouvez essayer de transformer votre champ Table_adrs en une structure adresse correcte :
complément adresse, numéro voie, type voie, nom_voie, distrib speciale, lieudit, code postal, cedex, numéro insee commune.
Une petite procédure pourrait traiter 99% des cas, une revue et correction manuelle s'imposant pour le reste.
Ai-je tout compris ou votre exemple n'était-il pas réel ?
J'ai ce script pour vérifier qu'une table n'a pas de trous dans les identifiants (obligation légale) :
with rech_trous as (
select id_registre as id,row_number() over (order by id_registre) as rn
from registre_mandat)
select id from rech_trous where id <> rn;
J'imagine qu'un limit 1 à la fin suffirait à donner le 1er numéro inutilisé.
Ma table ne fait que quelques milliers de lignes, donc je n'ai aucune idée des performances avec une volumétrie conséquente.
J'ai utilisé SQL Power Architect pour faire l'inverse, i.e. générer le modèle graphique
à partir de la base de données. Ca m'a permis de voir quelques oublis dans les relations.
Alex
En relisant les posts, je m'aperçois que vous n'avez pas mis le mot-clef delimiter entre parenthèses .
Ceci serait mieux :
COPY LaTableVierge FROM 'le\chemin\du\fichier\text' (delimiter ';');
Serait-ce votre souci ?
Une autre option est de créer un fichier sql de ce style :
COPY communes_cp (libcom, comcp, libdep, codcom, dat_creat, dat_tran, user_intranet_creat, user_intranet_tran, user_db_creat, user_db_tran) FROM stdin;
L ABERGEMENT CLEMENCIAT 01400 AIN 1001 \N \N \N \N \N \N
\.
La table concernée :
CREATE TABLE communes_cp (
libcom character varying(40) NOT NULL,
comcp character varying(5) NOT NULL,
libdep character varying(70) NOT NULL,
codcom character varying(5) NOT NULL,
dat_creat timestamp without time zone,
dat_tran timestamp without time zone,
user_intranet_creat character varying(40),
user_intranet_tran character varying(40),
user_db_creat character varying(40),
user_db_tran character varying(40)
);
Un exemple concret :
1) création table
CREATE TABLE villes (
nom_ville character varying(70),
nom_ville_maj character varying(70),
codpos character varying(5),
codcom character varying(5),
reg character varying(2),
lat numeric,
long numeric,
elg numeric
);
2) import (c'est sur Mac OS X)
copy villes from '/users/alex/Desktop/villes.csv' (delimiter ';');
Une ligne de mon fichier csv (pas de ligne d'entête) :
Ambronay;AMBRONAY;1500;1007;82;46;5.35;1.34
J'utilise phpPgAdmin qui me convient très bien : http://phppgadmin.sourceforge.net/doku.php?id=start
Alex
Si ça peut aider, voici la procédure de sauvegarde qui tourne chez nous (Ubuntu 12.04) :
DATE=$(date +%Y-%m-%d-%H-%M)
rm -f /var/lib/postgresql/conclavi_test.sql
pg_dumpall > /var/lib/postgresql/conclavi_test.sql
rm -f /var/lib/postgresql/backups/conclavi_test*.*
mv conclavi_test.sql /var/lib/postgresql/backups/conclavi_test-${DATE}.sql
tar -jcvf /var/lib/postgresql/backups/conclavi_test-${DATE}.bz2 /var/lib/postgresql/backups/conclavi_test-${DATE}.sql
echo 'Copie FTP'
ftp -in <<THEEND
open monftp
user monuser monpasswd
lcd backups
cd base-test
put conclavi_test-${DATE}.bz2
close
bye
THEEND
L'avantage de pg_dumpall est qu'il sauvegarde un cluster complet (rôles, bases...) .