Pages: 1
- Sujet précédent - Boucle pour créer plusieurs tables dans une fonction (postgres) - Sujet suivant
#1 Wed 04 July 2018 16:26
- bruhnild
- Participant actif
- Lieu: Lyon
- Date d'inscription: 7 Jun 2014
- Messages: 130
Boucle pour créer plusieurs tables dans une fonction (postgres)
Bonjour,
J'aimerais découper ma table t_adresse en autant de tables qu'il y a de valeurs uniques dans le champ nom_sro.
Le résultat serait semblable à celui ci :
Code:
CREATE TABLE rbal.t_adresse_nomsro1 AS SELECT * from rbal.t_adresse WHERE nom_sro LIKE '%nomsro1'; CREATE TABLE rbal.t_adresse_nomsro2 AS SELECT * from rbal.t_adresse WHERE nom_sro LIKE '%nomsro2'; CREATE TABLE rbal.t_adresse_nomsro3 AS SELECT * from rbal.t_adresse WHERE nom_sro LIKE '%nomsro3'; CREATE TABLE rbal.t_adresse_nomsro4 AS SELECT * from rbal.t_adresse WHERE nom_sro LIKE '%nomsro4'; etc.
Après quelques recherches, je suis tombée sur un exemple de fonction qui me permettrait de réaliser cette opération.
Ma fonction est la suivante :
Code:
CREATE OR REPLACE FUNCTION split_t_adresse() RETURNS VARCHAR as $$ DECLARE lv VARCHAR; BEGIN FOR lv IN SELECT DISTINCT nom_sro FROM rbal.t_adresse LOOP EXECUTE format(' DROP TABLE IF EXISTS rbal.t_adresse_'||lv||'; CREATE rbal.t_adresse_'||lv||' AS SELECT ad_code FROM rbal.t_adresse WHERE nom_sro ='||quote_literal(lv)||';'); END LOOP; END; $$ LANGUAGE plpgsql;
Lorsque je teste la fonction avec SELECT split_t_adresse(), celle ci me renvoie une erreur :
Code:
ERROR: ERREUR: erreur de syntaxe sur ou près de « rbal » LINE 5: CREATE rbal.t_adresse_N070GAY_S01C AS ^ QUERY: DROP TABLE IF EXISTS rbal.t_adresse_N070GAY_S01C; CREATE rbal.t_adresse_N070GAY_S01C AS SELECT ad_code FROM rbal.t_adresse WHERE nom_sro ='N070GAY_S01C'; CONTEXT: fonction PL/pgsql split_t_adresse(), ligne 9 à EXECUTE
Auriez vous une idée pour m'aiguiller vers la solution?
Merci d'avance pour vos retours.
Marine.
Hors ligne
#2 Wed 04 July 2018 16:54
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Boucle pour créer plusieurs tables dans une fonction (postgres)
Bonjour,
Il manque la parenthese apres EXECUTE format('
DROP TABLE IF EXISTS rbal.t_adresse_'||lv||';
Sinon, ne vous embetez pas avec une fonction pour faire cela: une requete SQL générant le SQL de creation (!!) peut suffire:
qq chose comme=
Code:
select 'create table rbal.t_adresse_'||lv||';' from ... where...
si vous executez cette requete dans psql, vous avez ensuite l'option (\gexec) pour executer le resultat de la requete comme nouvelles requetes SQL, donc vous créez directement les tables: treeees pratique
Nico
Dernière modification par Nicolas Ribot (Wed 04 July 2018 16:55)
Hors ligne
#3 Thu 05 July 2018 15:30
- bruhnild
- Participant actif
- Lieu: Lyon
- Date d'inscription: 7 Jun 2014
- Messages: 130
Re: Boucle pour créer plusieurs tables dans une fonction (postgres)
Bonjour,
Merci pour votre retour. J'ai suivi votre conseil et ai lancé la requête dans psql avec l'option \gexec.
Voici mon .bat (qui ne me retourne pas d'erreur):
Code:
cd C:\Program Files\PostgreSQL\10\bin\ set PGPASSWORD=psw psql.exe -h host -p 5432 -U postgres -W -d hsn -c "SELECT 'create table rbal.t_adresse_'||nom_sro||';'FROM (SELECT DISTINCT nom_sro FROM rbal.t_adresse) AS a " \gexec PAUSE
En PJ la capture d'écran de le fenêtre de commande après execution du .bat.
Le seul problème est que je ne retrouve pas mes 7 tables dans mon schéma rbal. Je dois mal avoir compris le fonctionnement de \gexec..
Hors ligne
#4 Thu 05 July 2018 18:03
Re: Boucle pour créer plusieurs tables dans une fonction (postgres)
Comme la copie d'écran le montre,vous ne spécifiez pas les colonnes de la table à créer.
Code:
psql.exe -h host -p 5432 -U postgres -W -d hsn -c "SELECT 'create table rbal.t_adresse_' || nom_sro || ' as select * from rbal.t_adresse where nom_sro = ' || nom_sro || ';' FROM (SELECT DISTINCT nom_sro FROM rbal.t_adresse) AS a " \gexec
Jean-Marie
Azimut
Hors ligne
#5 Mon 16 July 2018 09:17
- bruhnild
- Participant actif
- Lieu: Lyon
- Date d'inscription: 7 Jun 2014
- Messages: 130
Re: Boucle pour créer plusieurs tables dans une fonction (postgres)
Bonjour,
Merci pour votre retour. J'ai repris votre correction mais les tables ne s'écrivent pas et quand je l'exécute j'ai deux commentaires de psql:
1) l'option \gexec n'est pas prise en compte
2)il me demande de spécifier les colonnes alors que je lui demande de toutes les écrire (*). J'ai précisé les noms de quelques colonnes mais ça ne change rien au messages de sortie.
Code:
cd C:\Program Files\PostgreSQL\10\bin\ psql.exe -h host -p 5432 -U postgres -w -d hsn -c "SELECT 'create table rbal.t_adresse_' || nom_sro || ' as select * from rbal.t_adresse where nom_sro = ' || nom_sro || ';' FROM (SELECT DISTINCT nom_sro FROM rbal.t_adresse) AS a" \gexec PAUSE
Dernière modification par bruhnild (Mon 16 July 2018 09:18)
Hors ligne
#6 Mon 16 July 2018 10:16
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Boucle pour créer plusieurs tables dans une fonction (postgres)
Bonjour,
L'option \gexec est une option dynamique, lorsque vous etes connectées a psql. Elle ne marche pas en ligne de commande.
En ligne de commande, si vous voulez executer le résultat de requetes, il suffit de rediriger la sortie de psql vers un nouveau psql, et hop.
Je vous invite à bien tester d'abord les requêtes que vous générez, avant de les exécuter physiquement.
Nicolas
Hors ligne
#7 Mon 16 July 2018 10:38
- bruhnild
- Participant actif
- Lieu: Lyon
- Date d'inscription: 7 Jun 2014
- Messages: 130
Re: Boucle pour créer plusieurs tables dans une fonction (postgres)
Merci du conseil, j'étais justement en train de tester ma requête dans l'invite de commande psql. Je suis parvenue à un résultat satisfaisant avec cette requête :
Code:
SELECT 'drop table if exists rbal.t_adresse_' || nom_sro || '; create table rbal.t_adresse_'|| nom_sro || ' as select * from rbal.t_adresse where nom_sro =' || quote_literal(nom_sro) || ';' AS requete FROM (SELECT DISTINCT nom_sro FROM rbal.t_adresse) AS a \gexec
Je vais regarde comment executer mon résultat de requete en ligne de commande.
Bonne journée!
Dernière modification par bruhnild (Mon 16 July 2018 10:39)
Hors ligne
#8 Mon 16 July 2018 10:51
- bruhnild
- Participant actif
- Lieu: Lyon
- Date d'inscription: 7 Jun 2014
- Messages: 130
Re: Boucle pour créer plusieurs tables dans une fonction (postgres)
Pour appeler la requete dans un .bat:
Code:
cd C:\Program Files\PostgreSQL\10\bin\ psql.exe -h host -p 5432 -U postgres -w -d hsn -f C:\cheminverslesql\gexec_t_adresse.sql PAUSE
Hors ligne
Pages: 1
- Sujet précédent - Boucle pour créer plusieurs tables dans une fonction (postgres) - Sujet suivant