Vous n'êtes pas identifié(e).
- Contributions : Récentes | Sans réponse
Pages : 1
#1 Re : Général » distance entre deux points par une polyligne » 04/06/2014 12:00:03
Bonjour à tous,
J'ai finalement réussi à résoudre le problème.
Le script suivant (entre autres scripts et fonctions) a été décisif dans la résolution de mon problème :
WITH geoms AS(
Select gid_1, idf, fid_combin, code_zone2, geom, geom_2 as point1, geom_3 as point2
from v603_int)
SELECT row_number()OVER()::integer AS gid, gid_1, idf, fid_combin, code_zone2, geom, point1, point2,
ST_Length(ST_Line_Substring(geom, ST_Line_Locate_Point(geom, point1), ST_Line_Locate_Point(geom, point2))) as distance
FROM geoms;
J'avais préalablement joint dans une même table mes 3 couches (polyligne, point, point) afin d'avoir les 3 géométries sur la même table.
Ensuite, l'avant-dernière ligne de ce script est la plus importante. Par ST_Line_Substring, je crée une polyligne entre mes 2 points en passant par la polyligne du cours d'eau. Par ST_Length, je calcule la longueur de chacune des polylignes.
#2 Général » distance entre deux points par une polyligne » 02/06/2014 19:18:59
- Géronimo
- Réponses : 1
Bonsoir à tous,
Je vous expose mon problème :
J'ai 3 couches :
- une couche des cours d'eau, en géométrie polyligne. Il s'agit donc d'une arborescence de polyligne. Chaque branche de l'arbre représentant un tronçon hydrographique et donc une ligne sur la table attributaire de la couche.
- une couche des intersections de ces cours d'eau, en géométrie point. Chaque intersection des branches est un point et donc une ligne sur la table attributaire de cette couche.
- une couche de points parsemés sur les cours d'eau, en géométrie point. Les points sont placés sans logique particulière sur les tronçons hydrographiques.
Je voudrais, pour chaque point de la troisième couche, évaluer la distance qui le sépare de l'intersection des cours d'eau située juste en aval, c'est-à-dire des points de la deuxième couche.
Cela me permettra de sélectionner celui qui est le plus loin et d'effacer tous les autres, tronçons hydrographiques par tronçons hydrographiques.
Je veux bien sûr connaitre la distance entre ces points en passant par la polyligne du tronçon hydrographique et non par la distance la plus proche entre les deux.
Existe-t-il des requêtes ou des fonctions particulières sur postgresql permettant de calculer la distance entre deux points en passant par une polyligne, puis de résoudre mon problème ?
Je vous remercie de vos futures réponses.
A bientôt.
#3 Re : Général » Nommer les récursivités d'une requête récursive » 28/05/2014 11:00:38
Bijour !!!
Voilà le code qui m'a permis de résoudre mon problème :
WITH recursive rec (gid, profondeur, code_zone_max, code_zone, id_nd_ini, id_nd_fin, geom, chemin) AS (
SELECT gid, 1, code_zone, code_zone, id_nd_ini, id_nd_fin, geom, code_zone::text
FROM init_recurs_ord_7
union ALL
SELECT b.gid, a.profondeur +1, a.code_zone_max, b.code_zone, b.id_nd_ini, b.id_nd_fin, b.geom, a.chemin || ' > ' || b.code_zone
FROM rec a
INNER JOIN init_recurs_ord_7 b ON a.id_nd_fin = b.id_nd_ini)
SELECT * FROM rec
ORDER BY 1, profondeur DESC
#4 Re : Général » Nommer les récursivités d'une requête récursive » 27/05/2014 09:49:29
Désolé,
Je n'avais pas écrit correctement la 1ère fonction et la table qui en découlait hier soir. Surement la fatigue...
Donc, voilà la fonction :
WITH recursive rec (gid, profondeur, code_zone_max, code_zone, lettre_bv, id_nd_ini, id_nd_fin, rnk_link) AS (
SELECT gid, 1, code_zone, code_zone, lettre_bv, id_nd_ini, id_nd_fin, rnk_desc
FROM init_recurs_ord_2
union ALL
SELECT b.gid, a.profondeur +1, code_zone_max, b.code_zone, b.lettre_bv, b.id_nd_ini, b.id_nd_fin, b.rnk_desc
FROM rec a
INNER JOIN init_recurs_ord_2 b ON b.id_nd_fin = a.id_nd_ini)
SELECT * FROM rec
Et voilà la table qui en découle :
12;1;"V730";"V730";"V";619003051;619005470;1
11;1;"V721";"V721";"V";619002712;619003051;2
10;1;"V720";"V720";"V";619001184;619002712;3
9;1;"V700";"V700";"V";614010566;619001184;4
8;1;"X350";"X350";"X";619000786;614010566;5
7;1;"X348";"X348";"X";619000784;619000786;6
6;1;"X346";"X346";"X";619000560;619000784;7
5;1;"X345";"X345";"X";615009286;619000560;8
4;1;"X343";"X343";"X";615009662;615009286;9
3;1;"X342";"X342";"X";615009013;615009662;10
2;1;"X341";"X341";"X";614009387;615009013;11
1;1;"X340";"X340";"X";614008612;614009387;12
11;2;"V730";"V721";"V";619002712;619003051;2
10;2;"V721";"V720";"V";619001184;619002712;3
9;2;"V720";"V700";"V";614010566;619001184;4
8;2;"V700";"X350";"X";619000786;614010566;5
7;2;"X350";"X348";"X";619000784;619000786;6
6;2;"X348";"X346";"X";619000560;619000784;7
5;2;"X346";"X345";"X";615009286;619000560;8
4;2;"X345";"X343";"X";615009662;615009286;9
3;2;"X343";"X342";"X";615009013;615009662;10
2;2;"X342";"X341";"X";614009387;615009013;11
1;2;"X341";"X340";"X";614008612;614009387;12
10;3;"V730";"V720";"V";619001184;619002712;3
9;3;"V721";"V700";"V";614010566;619001184;4
8;3;"V720";"X350";"X";619000786;614010566;5
7;3;"V700";"X348";"X";619000784;619000786;6
etc...
3;10;"V730";"X342";"X";615009013;615009662;10
2;10;"V721";"X341";"X";614009387;615009013;11
1;10;"V720";"X340";"X";614008612;614009387;12
2;11;"V730";"X341";"X";614009387;615009013;11
1;11;"V721";"X340";"X";614008612;614009387;12
1;12;"V730";"X340";"X";614008612;614009387;12
On voit bien que ma deuxième colonne, la colonne profondeur a un numéro différent pour chaque récursivité. Je voudrais que, sur la troisième colonne (code_zone_max), apparaisse le nom du tronçon (code_zone) sur lequel s'effectue chaque récursivité.
Ainsi, à côté du 1 de la colonne profondeur pour la 1ère récursivité, il s'afficherait V730 sur les 12 lignes.
A côté du 2 de la colonne profondeur pour la 2e récursivité, il s'afficherait V720 sur 11 lignes.
...
A côté du 10 de la colonne profondeur pour la 10e récursivité, il s'afficherait X342 sur 3 lignes.
A côté du 11 de la colonne profondeur pour la 11e récursivité, il s'afficherait X341 sur 2 lignes.
A côté du 12 de la colonne profondeur pour la 12e récursivité, il s'afficherait X340 sur 1 lignes.
Je ne vois pas comment faire...
Merci de vos futures réponses.
#5 Général » Nommer les récursivités d'une requête récursive » 26/05/2014 19:24:21
- Géronimo
- Réponses : 2
Bonjour !
Je me permets de poster à nouveau ce sujet, mais dans un autre topic qui me semble plus adapté, car la fonction que j'avais écrite sur l'autre sujet (http://forums.postgresql.fr/viewtopic.php?id=3155) ne permet pas de nommer la récursivité d'une requête récursive comme il faut. Elle se contente de prendre la valeur maximum des code_zone et la met comme nom.
Voilà la table sur laquelle je travaille. Elle s'appelle init recurs_ord_2 :
gid ; rnk_desc ; profondeur ; code_hydro ; c_hyd_cdo, code_zone, lettre_bv, toponyme1, fpkh, tpkh, id_nd_ini, id_nd_fin
1;12;1;"V7300000";"V---0000";"V730";"V";"fleuve le rhône";947663;1000000;619003051;619005470
2;11;1;"V7210000";"V---0000";"V721";"V";"fleuve le rhône";944880;947663;619002712;619003051
3;10;1;"V7200000";"V---0000";"V720";"V";"fleuve le rhône";931497;944880;619001184;619002712
4;9;1;"V7000000";"V---0000";"V700";"V";"fleuve le rhône";916913;931497;614010566;619001184
5;8;1;"X3500000";"X---0000";"X350";"X";"rivière la durance";975886;1000000;619000786;614010566
6;7;1;"X3480400";"X34-0400";"X348";"X";"rivière le coulon";975108;1000000;619000784;619000786
7;6;1;"X3460400";"X34-0400";"X346";"X";"rivière le coulon";963787;975108;619000560;619000784
8;5;1;"X3450400";"X34-0400";"X345";"X";"rivière le calavon";955523;963787;615009286;619000560
9;4;1;"X3430400";"X34-0400";"X343";"X";"rivière le calavon";938396;955523;615009662;615009286
10;3;1;"X3420400";"X34-0400";"X342";"X";"rivière le calavon";935022;938396;615009013;615009662
11;2;1;"X3410400";"X34-0400";"X341";"X";"rivière le calavon";922089;935022;614009387;615009013
12;1;1;"X3400400";"X34-0400";"X340";"X";"rivière le calavon";913111;922089;614008612;614009387
Ce que je veux faire, c'est une récursivité par l'égalité id_nd_fin=id_nd_ini.
Cette table représente les tronçons hydrographiques de cours d'eau qui se suivent. Pour chacun des tronçons, de part et d'autres, il y a un identifiant : id_nd_ini pour l'extrémité la plus en amont et id_nd_fin pour l'extrémité la plus en aval. On comprend donc bien que, l'id_nd_fin d'un tronçon est égal à l'id_nd_ini du tronçon situé en aval.
Je veux donc que, pour chaque tronçon, le logiciel m'indique la liste des tronçons qui lui sont en amont.
Cela j'y arrive.
Ce que je veux, en plus, c'est que sur une des colonnes de la table qui m'est renvoyée, pour chaque liste, il soit indiqué le la nomenclature du tronçon dont est déployé toute la listes des tronçons qui lui sont en amont (l'identifiant code_zone).
Et ça je n'arrive pas à le faire...
J'arrive à ce qu'il me donne la récursivité pour chaque tronçon sans rangement par code_zone avec le code suivant :
WITH recursive rec (gid, profondeur, code_zone_max, code_zone, lettre_bv, id_nd_ini, id_nd_fin, rnk_link) AS (
SELECT gid, profondeur, code_zone, code_zone, lettre_bv, id_nd_ini, id_nd_fin, rnk_desc
FROM init_recurs_ord_2
union ALL
SELECT b.gid, a.profondeur, a.code_zone_max, b.code_zone, b.lettre_bv, b.id_nd_ini, b.id_nd_fin, b.rnk_desc
FROM rec a
INNER JOIN init_recurs_ord_2 b ON b.id_nd_fin = a.id_nd_ini )
SELECT * FROM rec
La table qui m'est retournée est :
gid, profondeur, code_zone_max, code_zone, lettre_bv, id_nd_ini, id_nd_fin, rnk_link
12;1;"V730";"V730";"V";619003051;619005470;1
11;1;"V721";"V721";"V";619002712;619003051;2
10;1;"V720";"V720";"V";619001184;619002712;3
9;1;"V700";"V700";"V";614010566;619001184;4
8;1;"X350";"X350";"X";619000786;614010566;5
7;1;"X348";"X348";"X";619000784;619000786;6
6;1;"X346";"X346";"X";619000560;619000784;7
5;1;"X345";"X345";"X";615009286;619000560;8
4;1;"X343";"X343";"X";615009662;615009286;9
3;1;"X342";"X342";"X";615009013;615009662;10
2;1;"X341";"X341";"X";614009387;615009013;11
1;1;"X340";"X340";"X";614008612;614009387;12
11;1;"V730";"V721";"V";619002712;619003051;2
10;1;"V721";"V720";"V";619001184;619002712;3
9;1;"V720";"V700";"V";614010566;619001184;4
8;1;"V700";"X350";"X";619000786;614010566;5
7;1;"X350";"X348";"X";619000784;619000786;6
6;1;"X348";"X346";"X";619000560;619000784;7
5;1;"X346";"X345";"X";615009286;619000560;8
4;1;"X345";"X343";"X";615009662;615009286;9
3;1;"X343";"X342";"X";615009013;615009662;10
2;1;"X342";"X341";"X";614009387;615009013;11
1;1;"X341";"X340";"X";614008612;614009387;12
etc...
3;1;"V730";"X342";"X";615009013;615009662;10
2;1;"V721";"X341";"X";614009387;615009013;11
1;1;"V720";"X340";"X";614008612;614009387;12
2;1;"V730";"X341";"X";614009387;615009013;11
1;1;"V721";"X340";"X";614008612;614009387;12
1;1;"V730";"X340";"X";614008612;614009387;12
78 lignes en tout.
J'arrive à avoir un rangement en fonction de code_zone, mais seulement sur une récursivité, avec cette fonction :
WITH recursive rec (gid, profondeur, code_zone_max, code_zone, lettre_bv, id_nd_ini, id_nd_fin, rnk_link) AS (
SELECT gid, profondeur, code_zone, code_zone, lettre_bv, id_nd_ini, id_nd_fin, rnk_desc
FROM init_recurs_ord_2
WHERE rnk_desc=1
union ALL
SELECT b.gid, a.profondeur, a.code_zone_max, b.code_zone, b.lettre_bv, b.id_nd_ini, b.id_nd_fin, b.rnk_desc
FROM rec a
INNER JOIN init_recurs_ord_2 b ON b.id_nd_fin = a.id_nd_ini AND a.rnk_link + 1 = b.rnk_desc)
SELECT * FROM rec
Qui me donne cette table :
gid, profondeur, code_zone_max, code_zone, lettre_bv, id_nd_ini, id_nd_fin, rnk_link
12;1;"V730";"V730";"V";619003051;619005470;1
11;1;"V730";"V721";"V";619002712;619003051;2
10;1;"V730";"V720";"V";619001184;619002712;3
9;1;"V730";"V700";"V";614010566;619001184;4
8;1;"V730";"X350";"X";619000786;614010566;5
7;1;"V730";"X348";"X";619000784;619000786;6
6;1;"V730";"X346";"X";619000560;619000784;7
5;1;"V730";"X345";"X";615009286;619000560;8
4;1;"V730";"X343";"X";615009662;615009286;9
3;1;"V730";"X342";"X";615009013;615009662;10
2;1;"V730";"X341";"X";614009387;615009013;11
1;1;"V730";"X340";"X";614008612;614009387;12
12 lignes
J'aimerais savoir si vous pouvez m'indiquer quel code utiliser pour avoir l'ensemble des récursivités (78 lignes comme sur la 1ère table) avec le rangement par code_zone (comme sur la deuxième table).
Je suis désolé pour le long poste, mais ça me semble indispensable pour tout décrire.
Je vous remercie d'avance pour vos futures réponses,
Bonne soirée.
#6 Re : PL/pgSQL » [9.3] nommer les récursions d'une requête récursive » 23/05/2014 17:20:56
Et voilà la réponse :
WITH RECURSIVE en_aval(profondeur, code_zone, id_nd_ini, id_nd_fin, geom) AS (
SELECT MAX(code_zone) OVER () AS profondeur, code_zone, id_nd_ini, id_nd_fin, geom FROM essai_pl
UNION ALL
SELECT MAX(e.code_zone) OVER () AS profondeur, e.code_zone, e.id_nd_ini, e.id_nd_fin, e.geom
FROM en_aval AS ea
INNER JOIN essai_pl AS e
ON e.id_nd_fin = ea.id_nd_ini)
SELECT ROW_NUMBER() OVER()::integer AS gid, profondeur, code_zone, id_nd_ini, id_nd_fin, geom FROM en_aval;
Bon week-end !
#7 Re : PL/pgSQL » fonction union de toutes les tables » 23/05/2014 16:35:28
T'avais peut-être pas mis de ; à la fin... Parce que moi, ça marche avec RETURN NEXT.
#8 Re : PL/pgSQL » fonction union de toutes les tables » 23/05/2014 16:33:21
Je crois que juste en modifiant le RETURN de ton premier script en RETURN NEXT, tu aurais pu avoir le même résultat...
#9 Re : PL/pgSQL » fonction union de toutes les tables » 23/05/2014 16:28:23
Essai RETURN NEXT à la place de ton RETURN à la fin de ton script...
#10 PL/pgSQL » [9.3] nommer les récursions d'une requête récursive » 23/05/2014 16:26:29
- Géronimo
- Réponses : 1
Bonjour à tous,
Voici ma requête :
WITH RECURSIVE en_aval(profondeur, code_zone, id_nd_ini, id_nd_fin, geom) AS (
SELECT 1, code_zone, id_nd_ini, id_nd_fin, geom
FROM essai_pl
UNION ALL
SELECT ea.profondeur + 1, e.code_zone, e.id_nd_ini, e.id_nd_fin, e.geom
FROM en_aval AS ea, essai_pl AS e
WHERE e.id_nd_fin = ea.id_nd_ini
)
SELECT row_number()OVER()::integer AS gid, * FROM en_aval
Dans la colonne "profondeur" de cette requête, il m'est indiquer un numéro pour chaque récursion (1 pour la première, 2 pour la seconde, 3 pour la troisième,...). J'aimerais remplacer ce numéro par l'identifiant de la zone où est pratiquée chaque récursion (code_zone). Il s'agit d'une chaîne de caractère sous la forme : lettre numéro numéro numéro.
Je vous remercie pour vos futures réponses.
Géronimo
#11 Re : PL/pgSQL » modification d'une table » 22/05/2014 11:05:17
gleu,
Je tiens à m'excuser du propos de mon dernier message. J'étais sur le coup de l'émotion, puisque ça faisait depuis 3 ou 4 jours que je cherchais en vain la solution en parcourant des dizaines de forum, tuto et cours. Ça m'a un peu poussé à bout, d'où la réaction très excessive de mon dernier message. J'espère que vous pourrez me pardonner, passer l'éponge et que si j'ai de nouveaux problèmes que je n'arrive pas à résoudre, vous aurez quand même envie de répondre à mes questions.
Bonne journée,
Géronimo.
#12 Re : PL/pgSQL » modification d'une table » 21/05/2014 15:08:16
Ca y est !!!
J'ai trouvé la réponse à mon problème ! Et tout seul en plus. J'ai parcouru des dizaines de forums, de cours et de tuto en français et en anglais et j'ai enfin trouvé comment modifier une table par des boucles !!!
Voici le script :
CREATE OR REPLACE FUNCTION essai()
RETURNS TABLE (ess_gid int, id_nd_ini cours_d_eau_par_noeuds_hydro_2.id_nd_ini%TYPE, id_nd_fin cours_d_eau_par_noeuds_hydro_2.id_nd_fin%TYPE,
geom cours_d_eau_par_noeuds_hydro_2.geom%TYPE, pkhexut cours_d_eau_par_noeuds_hydro_2.pkhexut%TYPE) AS
$BODY$
DECLARE
tables record;
BEGIN
FOR tables IN (SELECT row_number()OVER()::integer AS ess_gid, conh.id_nd_ini, conh.id_nd_fin, conh.geom, conh.pkhexut
FROM cours_d_eau_par_noeuds_hydro_2 as conh
ORDER BY ess_gid) LOOP
ess_gid := tables.ess_gid ; id_nd_ini := tables.id_nd_ini ; id_nd_fin := tables.id_nd_fin ;
geom := tables.geom ; pkhexut := tables.pkhexut ;
If pkhexut = 1000000 then
RETURN NEXT;
END IF;
END LOOP;
END;
$BODY$
LANGUAGE plpgsql;
Et là, ça me retourne le tableau avec les colonnes que je lui demande et les 90 lignes correspondant à la valeur 1000000 de la colonne pkhexut.
Bon, maintenant il me reste à faire les traitements complexes qu'impliquent mon projet... Et ce sera bien ça le plus dur !
Je posterai d'ailleurs sûrement dans le futur, ou peut-être pas. En tout cas, j'espère que vous serez plus loquaces que vous l'avez été pour ce sujet...
Comment fait-on pour déclarer ce sujet résolu ?
A bientôt !
#13 Re : PL/pgSQL » modification d'une table » 21/05/2014 12:36:15
Personne ne peut donc me répondre ?
C'est pourtant basique comme question... Je veux seulement savoir comment modifier une table par des boucles lorsqu'on est dans le cas d'un RETURNS TABLE (...).
#14 Re : PL/pgSQL » Fonction permettant de récupérer l'id et la géométrie de mes tables » 21/05/2014 11:19:14
Salut Sadewizz,
Voici la requête permettant de créer la numérotation des lignes de ta table :
SELECT row_number()OVER()::integer AS gid
Je pense qu'il faut que tu l'insères comme suit :
EXECUTE 'SELECT row_number()OVER()::integer AS id_table' || quote_ident(tables.tablename)
INTO id_table;
Je ne suis pas sûr que le quote_ident(tables.tablename) soit nécessaire dans ce cas-là.
Bon, après je suis débutant comme toi et je ne m'y connais pas encore parfaitement...
#15 Re : PL/pgSQL » modification d'une table » 20/05/2014 12:10:31
Aidez-moi, s'il vous plait. Je n'arrive pas à trouver ce que je ne fais pas bien dans mon code.
J'arrive sur deux cas. Pour le premier, j'écris la requête à l'intérieur de la boucle du FOREACH, comme suit :
CREATE OR REPLACE FUNCTION essai()
RETURNS TABLE (ess_gid int, id_nd_ini cours_d_eau_par_noeuds_hydro_2.id_nd_ini%TYPE, id_nd_fin cours_d_eau_par_noeuds_hydro_2.id_nd_fin%TYPE,
geom cours_d_eau_par_noeuds_hydro_2.geom%TYPE, pkhexut cours_d_eau_par_noeuds_hydro_2.pkhexut%TYPE) AS
$BODY$
DECLARE
pkhexut cours_d_eau_par_noeuds_hydro_2.pkhexut%TYPE;
pkhtest numeric :=1000000;
BEGIN
IF (pkhexut is NOT NULL) THEN
FOREACH pkhtest in ARRAY pkhexut
LOOP
RETURN QUERY SELECT row_number()OVER()::integer AS ess_gid, conh.id_nd_ini, conh.id_nd_fin, conh.geom, conh.pkhexut
FROM cours_d_eau_par_noeuds_hydro_2 as conh
ORDER BY ess_gid;
END LOOP;
END IF;
END;
$BODY$
LANGUAGE plpgsql;
Et lorsque j'exécute le "select * from essai()", il me renvoie un tableau vide avec seulement le nom des colonnes.
Pour le deuxième cas, j'écris la requête à l'extérieur des boucles, comme suit :
CREATE OR REPLACE FUNCTION essai()
RETURNS TABLE (ess_gid int, id_nd_ini cours_d_eau_par_noeuds_hydro_2.id_nd_ini%TYPE, id_nd_fin cours_d_eau_par_noeuds_hydro_2.id_nd_fin%TYPE,
geom cours_d_eau_par_noeuds_hydro_2.geom%TYPE, pkhexut cours_d_eau_par_noeuds_hydro_2.pkhexut%TYPE) AS
$BODY$
DECLARE
pkhexut cours_d_eau_par_noeuds_hydro_2.pkhexut%TYPE;
pkhtest numeric :=1000000;
BEGIN
IF (pkhexut is NOT NULL) THEN
FOREACH pkhtest in ARRAY pkhexut
LOOP
END LOOP;
END IF;
RETURN QUERY SELECT row_number()OVER()::integer AS ess_gid, conh.id_nd_ini, conh.id_nd_fin, conh.geom, conh.pkhexut
FROM cours_d_eau_par_noeuds_hydro_2 as conh
ORDER BY ess_gid;
END;
$BODY$
LANGUAGE plpgsql;
Et là, lorsque j'exécute "select * from essai()", il me renvoie un tableau avec tous les noms des colonnes, mais avec toutes les lignes de la table "cours_d_eau_par_noeuds_hydro_2" alors que je ne lui ai demandé que les lignes où les valeurs de la colonne "pkhexut" sont égales à 1000000. Du coup, il me renvoie un tableau à 279 lignes au lieu d'un tableau à 90 lignes (vu qu'il y a 90 fois 1000000 dans cette colonne)...
J'ai vraiment besoin de savoir comment modifier une table avec des boucles, même pour ce cas simple que je pourrais résoudre dans une simple requête SQL en rajoutant une ligne : "WHERE conh.pkhexut=1000000". Mais c'est pour, plus tard, effectuer des traitements complexes qui exigent l'intervention de boucle. Ainsi, si je sais comment modifier une table avec des boucles simples, j'aurais des pistes pour le faire avec des boucles complexes.
Je vous remercie d'avance pour vos futures réponses.
De mon côté, je vais continuer mes tests...
#16 Re : PL/pgSQL » modification d'une table » 20/05/2014 08:32:27
Merci gleu pour ta réponse.
J'ai suivi ta recommandation et j'ai fait la modification qui suit :
BEGIN
IF (pkhexut is NOT NULL) THEN
totdiff:=totdiff+1;
pkhexut[totdiff]:=pkh;
FOREACH pkhtest in ARRAY pkhexut
LOOP
Du coup, maintenant il ne m'embête plus avec des valeurs NOT NULL, mais lorsque je teste le "select * from essai()", il ne me met plus de message d'erreur, mais il m'indique juste les noms des colonnes sans mettre aucune valeur de la table...
Comment faire en sorte qu'il m'affiche les lignes correspondantes à la valeur 1000000 de la colonne pkhexut ?
#17 PL/pgSQL » modification d'une table » 19/05/2014 17:10:37
- Géronimo
- Réponses : 7
Bonjour à tous,
Je suis nouveau sur ce forum, mais aussi pour la programmation en pl/pgSQL. Avant d'écrire ce message, j'ai parcouru le forum par l'option recherche, mais je n'ai pas trouvé la solution à mon problème qui me parait pourtant basique.
Comme indiqué dans le sujet du message, je veux pouvoir modifier ma table sur pl/pgSQL pour ensuite l'afficher par un CREATE VIEW basique sur postgresql.
Ce que je veux précisément faire dans la fonction, c'est d'afficher les colonnes "ess_gid", "id_nd_ini", "id_nd_fin", "geom", "pkhexut" de la table "cours_d_eau_par_noeuds_hydro_2" lorsque les valeurs de la colonne pkhexut sont égales à 1000000. Je sais que c'est faisable directement sur PostgreSQL, mais je dois le réussir cette étape sur pl/pgSQL, parce que je ferais, plus tard, des traitements qui nécessiteront absolument ce langage, par l'utilisation de boucles. Je teste donc une boucle "simple" afin de me lancer plus tard dans des boucles plus complexes.
Après de multiples et nombreuses recherches sur le net, j'en suis arrivé à ce script :
DROP FUNCTION essai() CASCADE
CREATE OR REPLACE FUNCTION essai()
RETURNS TABLE (ess_gid int, id_nd_ini cours_d_eau_par_noeuds_hydro_2.id_nd_ini%TYPE, id_nd_fin cours_d_eau_par_noeuds_hydro_2.id_nd_fin%TYPE,
geom cours_d_eau_par_noeuds_hydro_2.geom%TYPE, pkhexut cours_d_eau_par_noeuds_hydro_2.pkhexut%TYPE) AS
$BODY$
DECLARE
totdiff integer;
pkhexut numeric[];
pkh numeric;
pkhtest numeric :=1000000;;
BEGIN
totdiff:=totdiff+1;
pkhexut[totdiff]:=pkh;
IF (pkhexut is NOT NULL) THEN
FOREACH pkhtest in ARRAY pkhexut
LOOP
RETURN QUERY
SELECT row_number()OVER()::integer AS ess_gid, conh.id_nd_ini, conh.id_nd_fin, conh.geom, conh.pkhexut
FROM cours_d_eau_par_noeuds_hydro_2 as conh
ORDER BY ess_gid;
END LOOP;
END IF;
END;
$BODY$
LANGUAGE plpgsql;
CREATE or replace VIEW essai1 as
select * from essai()
Lorsque je teste la fonction en elle-même, il m'est indiqué :
NOTICE: référence de type cours_d_eau_par_noeuds_hydro_2.id_nd_ini%TYPE convertie en numeric
NOTICE: référence de type cours_d_eau_par_noeuds_hydro_2.id_nd_fin%TYPE convertie en numeric
NOTICE: référence de type cours_d_eau_par_noeuds_hydro_2.geom%TYPE convertie en geometry
NOTICE: référence de type cours_d_eau_par_noeuds_hydro_2.pkhexut%TYPE convertie en numeric
La requête a été exécutée avec succès en 12 ms, mais ne renvoie aucun résultat.
Donc, pas de problème. Par contre, lorsque je teste la ligne
select * from essai()
, il m'est indiqué :
ERREUR: un indice de tableau dans une affectation ne peut pas être NULL
CONTEXT: fonction PL/pgsql essai(), ligne 9 à affectation
********** Erreur **********
ERREUR: un indice de tableau dans une affectation ne peut pas être NULL
État SQL :22004
Contexte : fonction PL/pgsql essai(), ligne 9 à affectation
Il m'indique que l'affectation ne peut pas être NULL alors que je précise justement IS NOT NULL à cet endroit.
Quel est le problème ?
Est-ce que j'utilise vraiment la bonne démarche pour ce que je veux faire ?
Merci d'avance de vos réponses...
Pages : 1