Annonce
Pour sa 21ème année, l’association GeoRezo a toujours besoin de vous !
10€ = 1 mois de frais bancaires ; 15€ = 12 mois de nom de domaine ; 30€ = 1 semaine de location des serveurs …
Retrouver nos membres bienfaiteurs
#1 Wed 27 July 2022 20:06
- philippe_schitter
- Juste Inscrit !
- Date d'inscription: 27 Jul 2022
- Messages: 1
Boucle pour creer N tables dans une fonction (postgres)
Bonjour,
Suite à votre discussion et sur la même logique, je rencontre une erreur que je n'arrive pas à résoudre.
Je travaille dans les télécom et je souhaite diviser une table de câbles "CB" en x tables en fonction des x valeurs uniques du champ "mode_pose".
Après consultation des tutoriels et forums, j'ai rédigé en PL/pgSQL le code copié ci-dessous :
Code:
CREATE OR REPLACE FUNCTION split_CB() RETURNS VARCHAR as $$ DECLARE x VARCHAR; BEGIN FOR x IN SELECT DISTINCT CB."mode_pose" FROM "syane_test"."CB" CB LOOP EXECUTE format(' DROP TABLE IF EXISTS syane_test.CB_'||x||'; CREATE TABLE syane_test.CB_'||x||' AS SELECT * FROM "syane_test"."CB" CB WHERE CB."mode_pose" ='||quote_literal(x)||';'); END LOOP; END; $$ LANGUAGE plpgsql; SELECT split_CB();
et je me suis heurté à un message d'erreur suivant :
"""
NOTICE: la table « cb_aerien » n'existe pas, poursuite du traitement
CONTEXT: instruction SQL «
DROP TABLE IF EXISTS syane_test.CB_AERIEN;
CREATE TABLE syane_test.CB_AERIEN AS
SELECT *
FROM "syane_test"."CB" CB
WHERE CB."mode_pose" ='AERIEN'; »
fonction PL/pgsql split_cb(), ligne 9 à EXECUTE
NOTICE: la table « cb_immeuble » n'existe pas, poursuite du traitement
CONTEXT: instruction SQL «
DROP TABLE IF EXISTS syane_test.CB_IMMEUBLE;
CREATE TABLE syane_test.CB_IMMEUBLE AS
SELECT *
FROM "syane_test"."CB" CB
WHERE CB."mode_pose" ='IMMEUBLE'; »
fonction PL/pgsql split_cb(), ligne 9 à EXECUTE
NOTICE: la table « cb_souterrain » n'existe pas, poursuite du traitement
CONTEXT: instruction SQL «
DROP TABLE IF EXISTS syane_test.CB_SOUTERRAIN;
CREATE TABLE syane_test.CB_SOUTERRAIN AS
SELECT *
FROM "syane_test"."CB" CB
WHERE CB."mode_pose" ='SOUTERRAIN'; »
fonction PL/pgsql split_cb(), ligne 9 à EXECUTE
ERREUR: le contrôle a atteint la fin de la fonction sans RETURN
CONTEXT: fonction PL/pgsql split_cb()
********** Erreur **********
ERREUR: le contrôle a atteint la fin de la fonction sans RETURN
État SQL :2F005
Contexte : fonction PL/pgsql split_cb()
"""
Pouvez-vous m'aider à résoudre cette erreur ?
Et si oui, dans la foulée, est-il possible d'intégrer aux nouvelles tables, la création en boucle de Contraintes de clé primaire ?
Merci par avance, bien cordialement.
Hors ligne
#2 Thu 28 July 2022 10:09
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Boucle pour creer N tables dans une fonction (postgres)
Bonjour,
Ce doit etre du à un problème sur le nom des tables, qui contiennent des majuscules.
Je vous conseille de créer vos tables en minuscule, sans mettre de "" autour de leur nom, sinon le nom devient case-sensitive.
Pour éviter ces erreurs, il faut utiliser la fonction format en passant les paramètres à ecrire dans la string sous forme de parametre de la fonction et pas en faisant string || string (https://www.postgresql.org/docs/14/func … tring.html):
Code:
... EXECUTE format('DROP TABLE IF EXISTS %I.%I;', table_schema, x);
Format accepte différents formatter, dont %I qui se charge de mettre des "" si besoin au nom des tables.
Je ne suis pas sur que ce soit une bonne solution en terme de modèle de créer ces tables: il faut mieux en faire une seule, qui contient dans une colonne les valeurs de mode_pose et qui vous permettra de filtrer sur cette colonne pour avoir les informations relatives.
Ca vous permettra de faire des traitements automatiques plus facilement, car sinon, il faudra créer des requetes à partir de string, en remplaçant le nom des tables que vous voulez interroger.
Nicolas
Hors ligne
#3 Thu 28 July 2022 11:31
Re: Boucle pour creer N tables dans une fonction (postgres)
Bonjour,
Je ne suis pas sur que ce soit une bonne solution en terme de modèle de créer ces tables: il faut mieux en faire une seule, qui contient dans une colonne les valeurs de mode_pose et qui vous permettra de filtrer sur cette colonne pour avoir les informations relatives.
Ca vous permettra de faire des traitements automatiques plus facilement, car sinon, il faudra créer des requetes à partir de string, en remplaçant le nom des tables que vous voulez interroger.
Nicolas
Gros +1
Au pire, si vos tenez à simplifier certaines requêtes, vous pouvez toujours créer des vues
Jean-Marie
Azimut
Hors ligne
#4 Thu 28 July 2022 13:55
- p.jeremie
- Participant assidu
- Lieu: Valence
- Date d'inscription: 10 Sep 2017
- Messages: 431
Re: Boucle pour creer N tables dans une fonction (postgres)
+1 également.
Très bonne remarque sur les vues, est-ce ça répondrait à votre besoin Philippe ?
Hors ligne