Vous n'êtes pas identifié(e).
Pages : 1
Bonjour,
je fais actuellement face à un soucis.
Je possède une table "source" qui contient des lignes que je dispatche par la suite dans d'autres tables via un attribut spécifique.
Ce que j'essaie d'avoir, c'est une comparaison entre ce qui existe dans la table source, et ce qui est exporté dans les autres tables afin de voir si il n'y a pas d'oublie (question de paranoïa).
la requête ci dessous me donne bien ce que je cherche mais uniquement entre deux tables (la table source et une seul table de dispatche):
select
matable1.plandxf as plandxf,
count(distinct matable1.gid) as table_destination,
count(distinct matable2.gid) as table_source
from monschema.matable1
left join monschema.matable2
on matable2.plandxf=matable1.plandxf
group by matable1.plandxf
le résultat en sortie:
plandxf table_destination table_source
-------- ----------------- -------------
ACCEHAND 2112 2112
GUE 59 59
PASSEREL 773 773
j'ai donc essayé de créer une fonction qui me permettrais de factoriser cette requête et ainsi de comparer ma table source à toute mes tables de dispatches et qu'elle me sorte un tableaux similaire au précédent.
Je pourrais ainsi récupérer le résultat de cette requête via un autre logiciel métier.
Voici ma "fonction" actuelle. Elle ce lance mais ne ressort pas de résultat ni de tableaux...
CREATE OR REPLACE FUNCTION monschema.sig_count3()
RETURNS TABLE(plandxf character varying, table character varying, c character varying) AS
$BODY$
DECLARE
liste RECORD;
BEGIN
FOR liste IN (select tablename from pg_tables where tablename = 'matable1')
LOOP
execute'select '
||liste.tablename||'.plandxf as plandxf,
count(distinct '||liste.tablename||'.gid) as table_destination,
count(distinct matable2.gid) as table_source from monschema.'||liste.layer||'
left join monschema.matable2
on matable2.plandxf='||liste.tablename||'.plandxf
group by '||liste.tablename||'.plandxf;';
END LOOP;
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION monschema.sig_count3()
OWNER TO postgres;
Si quelqu'un à la solution, je suis preneur
Merci à vous ^^
Sadewizz
Bonjour Geo-x,
Merci pour votre réponse.
Effectivement le trigger n'agit pas sur la bonne fonction. J'ai vraisemblablement fais une erreur lors de mon copier coller.
Mon but était d'avoir une souche d'intersection dynamique. De ce fait une vue me semblait répondre au problème, cependant j'ai pu observer une certaine lenteur lors de l'import de cette vue dans mon client carto. Alors qu'il n'y a que 74 lignes. La même couche mais cette fois ci en table, s'importe sans problème.
Avez vous une idée sur le pourquoi de cette lenteur?
Sadewizz
Bonjour,
Est il possible d'implémenter une table en effectuant une requête via un trigger, sur des données issues d'une vue ?
J'ai pour l'instant cette fonction
CREATE OR REPLACE FUNCTION za()
RETURNS trigger AS
$BODY$
DECLARE
BEGIN
INSERT INTO za SELECT row_number() OVER (ORDER BY france_littoral.id) AS gid,
new.table_liste_emprise.nom_donnee,
france_littoral.id AS zone,
france_littoral.the_geom_wgs84
FROM france.france_littoral,
france.table_liste_emprise
WHERE st_intersects(france_littoral.the_geom_wgs84, table_liste_emprise.the_geom_wgs84);
RETURN NEW;
return null;
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION za()
OWNER TO postgres;
------------------------------------------------------------------------
CREATE TRIGGER zone_geo
INSTEAD OF INSERT ON zone_geographique
FOR EACH ROW
EXECUTE PROCEDURE za();
Ici, j'essaie de réaliser la requête en fonction des nouveaux ajouts dans la vue "table_liste_emprise", et d'implémenter le résultat dans la table "za".
Cependant le trigger ne marche pas alors que le code s’exécute bien.
D'ou ma question : Est ce possible de réaliser ce genre d'opération ?
Merci d'avance.
Sadewizz
Bonjour,
Merci pour votre réponse. J'ai suivi vos conseils et j'ai utilisé la fonction LOWER pour changer le contenu du deuxième record (geom)
FOR geom IN SELECT LOWER(type) FROM geometry_columns where f_table_schema='france' AND f_table_name = liste.tablename
Cela fonctionne parfaitement. Merci pour votre aide!!
Bonne journée.
Sadewizz
Salut,
J'ai récemment essayer de créer une fonction me permettant de mettre à jour chaque table lors de son insertion dans la base de donnée.
Cependant j'ai un soucis, lorsque je lui dis de créer une nouvelle colonne géométrique. Il faut lui spécifier le type de géométrie de la couche, ce que je fais. Mais le problème est que le type ressort avec un double guillemets.
Voici mon code. L'erreur survient au premier "execute" à la ligne 18.
CREATE OR REPLACE FUNCTION france.maj_2()
RETURNS void AS
$BODY$
DECLARE
liste RECORD;
geom RECORD;
BEGIN
FOR liste IN SELECT tablename FROM pg_tables where tablename
IN
(select tablename from pg_tables where schemaname ='france' and tablename in
(SELECT f_table_name FROM geometry_columns
where f_table_name not like 'france_littoral'))
loop
FOR geom IN SELECT type FROM geometry_columns where f_table_schema='france' AND f_table_name = liste.tablename
loop
IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'france' AND TABLE_NAME = liste.tablename AND COLUMN_NAME = 'the_geom_wgs84')
THEN
execute'select addgeometrycolumn ('''','''||quote_ident(liste.tablename)||''',''the_geom_wgs84'',''4326'','''||quote_ident(geom.type)||''',2);
update '||quote_ident(liste.tablename)||' set the_geom_wgs84= st_transform(the_geom_orig,4326);';
IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'france' AND TABLE_NAME = liste.tablename AND COLUMN_NAME = 'nom_donnee')
THEN
execute'ALTER TABLE '||quote_ident(liste.tablename)||' ADD COLUMN nom_donnee varchar(80);
update '||quote_ident(liste.tablename)||' set nom_donnee='''||quote_ident(liste.tablename)||''';';
IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'france' AND TABLE_NAME = liste.tablename AND COLUMN_NAME = 'id')
THEN
execute'ALTER TABLE '||quote_ident(liste.tablename)||' ADD COLUMN id varchar(80);
ALTER TABLE '||quote_ident(liste.tablename)||' drop constraint '||quote_ident(liste.tablename)||'_pkey;
UPDATE '||quote_ident(liste.tablename)||' set id = nom_donnee||''_''||nextval(''france.id_seq''::regclass);
ALTER TABLE '||quote_ident(liste.tablename)||' add constraint '||quote_ident(liste.tablename)||'_pkey primary key(id);';
end if;
end if;
end if;
end loop;
end loop;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION france.emprise_table()
OWNER TO postgres;
Il me sort donc l'erreur suivante :
ERREUR: la colonne « POINT » n'existe pas
LINE 1: ...addgeometrycolumn ('','b','the_geom_wgs84','4326',"POINT",2)...
^
QUERY: select addgeometrycolumn ('','b','the_geom_wgs84','4326',"POINT",2);
update b set the_geom_wgs84= st_transform(the_geom_orig,4326);
CONTEXT: fonction PL/pgsql maj_2(), ligne 16 à instruction EXECUTE
********** Erreur **********
ERREUR: la colonne « POINT » n'existe pas
État SQL :42703
Contexte : fonction PL/pgsql maj_2(), ligne 16 à instruction EXECUTE
D'après vous, comment puis je retirer ces doubles guillemets? Avez vous une idée?
Merci pour vos éventuelles réponses et bonne soirée (ou journée pour certains) ;D
Sadewizz.
Bonjour,
Oui effectivement, j'ai entre temps changé le nom de la fonction désolé. Mais l'erreur reste la même.
J'ai néanmoins réussi à résoudre mon problème.
CREATE OR REPLACE FUNCTION france.emprise_table()
RETURNS void AS
$BODY$
DECLARE
liste RECORD;
rec RECORD;
curs refcursor;
BEGIN
FOR liste in select nom_donnee FROM france.table_liste
LOOP
EXECUTE 'CREATE or replace view france.'||quote_ident(liste.tablename)||'_emp AS
SELECT nom_donnee, st_convexhull( st_collect (the_geom_wgs84)) as the_geom_wgs84
FROM '||quote_ident(liste.tablename)||' group by nom_donnee;';
END LOOP;
OPEN curs FOR SELECT nom_donnee FROM table_liste;
LOOP
FETCH curs INTO rec;
exit when not found;
END LOOP;
CLOSE curs;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION france.emprise_table()
OWNER TO postgres;
A priori il manquait des LOOP et certains étaient mal placés.
Merci pour vos aides.
Sadewizz
Merci pour votre réponse, et l'intérêt porté à mon post.
J'ai suivi vos conseils et j'ai commencé par réaliser une fonction que j’appellerais ensuite dans le trigger de la table en question.
Seulement pg_admin me retourne erreur que je ne comprend pas lorsque j'appel ma fonction avec un select * from mafonction().
Voici ma fonction:
CREATE OR REPLACE FUNCTION france.emprise_table() RETURNS void AS $$
DECLARE
liste RECORD;
rec RECORD;
curs refcursor;
BEGIN
FOR liste in select nom_donnee from france.table_liste
LOOP
perform 'CREATE table france.'||quote_ident(liste.nom_donnee)||'_emp AS
SELECT nom_donnee, st_convexhull( st_collect (the_geom_wgs84))
FROM '||quote_ident(liste.nom_donnee)||' group by nom_donnee;';
OPEN curs FOR SELECT nom_donnee FROM table_liste;
FETCH curs INTO rec;
END LOOP;
CLOSE curs;
END;
$$ LANGUAGE plpgsql;
Et le message d'erreur qui en découle :
ERREUR: curseur « <unnamed portal 149> » déjà en cours d'utilisation
CONTEXT: fonction PL/pgsql fct(), ligne 12 à OPEN
********** Erreur **********
ERREUR: curseur « <unnamed portal 149> » déjà en cours d'utilisation
État SQL :42P03
Contexte : fonction PL/pgsql fct(), ligne 12 à OPEN
D'où pourrait venir le problème d'après vous?
Enfin, tout d'abord ma fonction n'est peut-être pas exact...
Bonjour,
Merci pour votre réponse!
J'avais déjà lu la doc que vous m'avez conseillé, cependant les fonction triggers, il me semble, n'effectue pas de "create table" si?
Plus simplement je voudrait créer une fonction me permettant un "create table T as select st_convexhull(the_geom)" (la syntaxe est à titre indicatif), dés l'insertion d'une nouvelle table.
Je ne sais pas si ce que je souhaite est possible, qu'en pensé vous?
Sadewizz
Bonjour,
je suis novice en ce qui concerne postgres/gis, et dans le cadre d'un stage je suis amené à créer une base donnée spatiale.
Ma question est la suivante: Une fonction plp/gsql ou autre peut elle générer automatiquement une table ?
Je m'explique. j'ai déjà une vue me permettant de lister toutes me tables de manière dynamique. Mais je voudrait qu'a l'insertion de chaque table, une fonction, ou plusieurs, me récupère le nom de la nouvelle table dans la liste en question, et crée une autre nouvelle table de style st_convexhull à partir de cette nouvelle table en récupérant juste les informations souhaitées.
Cela est il possible ?
Merci pour vos réponses,
Sadewizz.
Salut Géronimo,
Il me semble qu'avec "RETURN NEXT", il me signalait un erreur de syntaxe...
Mais merci pour ton intervention .
Re salut,
Pour ceux que sa intéressent, j'ai pu résoudre mon problème (avec un peu de chance).
--drop function table_union();
CREATE OR REPLACE FUNCTION table_union () RETURNS table (i varchar, n varchar, g geometry)
language plpgsql
as
$BODY$
DECLARE
tables record;
BEGIN
FOR tables IN SELECT tablename FROM pg_tables where tablename
IN
(select tablename from pg_tables where schemaname ='france' and tablename in (SELECT f_table_name FROM geometry_columns where f_table_name not like '%_t' and f_table_name not like 'france_littoral' and f_table_name not like 'box%' and f_table_name not like 'rast%'))
LOOP
return query Execute 'select '||quote_ident (tables.tablename)||'.id , '||quote_ident(tables.tablename)||'.nom_donnee, '||quote_ident(tables.tablename)||'.the_geom_wgs84 from '||quote_ident(tables.tablename)||';'
RETURN ;
END LOOP;
END
$BODY$;
Le "RETURN QUERY" a tout changé il faut croire.
Bon week end!
Sadewizz (steack de cerf! )
Bonjour,
Ci dessous j'ai essayer de mettre en place une fonction me permettant de récupérer certaines infos sur mes tables en faisant une union entre elles.
seulement la fonction s'effectue mais me renvoie 0 résultat avec la requête suivante :
select * from table_union();
Mon code :
CREATE OR REPLACE FUNCTION table_union () RETURNS table(i text, n text, g geometry)
language plpgsql
as
$BODY$
DECLARE
tables record;
BEGIN
FOR tables IN SELECT tablename FROM pg_tables where tablename
IN
(select tablename from pg_tables where schemaname ='france' and tablename in (SELECT f_table_name FROM geometry_columns where f_table_name not like '%_t' and f_table_name not like 'france_littoral' and f_table_name not like 'box%' and f_table_name not like 'rast%'))
LOOP
Execute 'select '||quote_ident (tables.tablename)||'.id as id, '||quote_ident(tables.tablename)||'.nom_donnee as nom, '||quote_ident(tables.tablename)||'.the_geom_wgs84 as yhe_geom from '||quote_ident(tables.tablename)||';'
RETURN ;
END LOOP;
END
$BODY$;
Avez vous une idée de la provenance de mon / mes erreurs?
Merci pour d'éventuelles éclaircicement et bon week end a vous!!
Salut Géronimo,
Merci pour ta réponse. Cependant le résultat obtenu avec Row_number ne me numérote que les lignes des tables dont les id ont été extraient. Comme il ne m'extrait qu'une seule ligne par table me met 1 à chaque ligne.
Enfin pour ma part il me semble que ce soit çà...
En tout cas merci pour ton aide. Je continue de chercher et apporterais une solution si toutefois j'en trouve une.
Mais si quelqu'un à deux ou trois pistes, je suis preneur
Bonne après midi!!
Fonction permettant de récupérer l'id et la géométrie de mes tables
Bonjour,
Je suis nouveau sur le site. J'espere pouvoir trouver un peu d'aide ici.
J'ai un petit problème avec une fonction :
CREATE OR REPLACE FUNCTION test3(OUT nom_table text, OUT id_table text, OUT table_geometry geometry ) RETURNS SETOF record
LANGUAGE plpgsql
AS
$BODY$
DECLARE
tables record;
BEGIN
FOR tables IN SELECT tablename FROM pg_tables where tablename
IN
(
(SELECT f_table_name FROM geometry_columns where f_table_name not like 'box_%' and f_table_name not like 'rast%')
UNION (SELECT 'spatial_ref_sys') UNION (select f_geometry_column from geometry_columns where f_geometry_column not like 'the_geom_wgs84')
)
AND pg_tables.schemaname='france'
LOOP
nom_table := tables.tablename;
EXECUTE 'SELECT id FROM '|| quote_ident(tables.tablename)
INTO id_table;
EXECUTE 'SELECT the_geom_wgs84 FROM ' || quote_ident(tables.tablename)
INTO table_geometry;
RETURN NEXT;
END LOOP;
END
$BODY$;
Cette fonction me renvoie comme résultat, un tableau contenant le nom de ma donnée, un id pris au hasard (je suppose ?) et une ligne géométrique.
Cependant, impossible de visualiser çà dans un client carto.
Ce que je voudrais c'est pouvoir récupérer chaque ligne de mes tables en fonction de leurs id (qui est unique) et leurs coordonnées géométriques.
Tout d'abord, est ce possible ?
Merci d'avance pour d'éventuelle réponse.
S.
Pages : 1