banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

Rencontres QGIS 2025

L'appel à participation est ouvert jusqu'au 19 janvier 2025!

#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..


Fichier(s) joint(s) :
Pour accéder aux fichiers vous devez vous inscrire.

Hors ligne

 

#4 Thu 05 July 2018 18:03

jmarsac
Participant assidu
Lieu: NICE
Date d'inscription: 26 Oct 2005
Messages: 572
Site web

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)


Fichier(s) joint(s) :
Pour accéder aux fichiers vous devez vous inscrire.

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)


Fichier(s) joint(s) :
Pour accéder aux fichiers vous devez vous inscrire.

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

 

Pied de page des forums

Powered by FluxBB