Est-il possible de choisir parmi toutes les tables à l'intérieur du schéma? J'ai eu tous les noms de table de
select table_name from information_schema.tables
mais je suis incapable de l'utiliser pour faire ma requête.
Vous ne pouvez pas le faire directement car on ne peut pas écrire une requête "normale" si les noms de table ne sont pas connus (c'est-à-dire provenant d'une variable ou d'une sous-requête). Mais vous pouvez construire et exécuter une instruction SQL dynamique pour cela. Par exemple, si vous avez besoin de la colonne 'Nom' de chaque table, vous pouvez effectuer ce qui suit (à l'intérieur d'une fonction PL/PGSQL ):
FOR i IN SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'your_desired_schema'
LOOP
sql_string := sql_string || format($$
-- some whitespace is mandatory here
UNION
SELECT name FROM %I
$$,
i.table_name);
END LOOP;
EXECUTE sql_string;
Dans ce formulaire, cela ne fonctionnera cependant pas, car vous ne pouvez pas SELECT
in plpqsql
si vous ne le faites pas dans une variable. Vous pouvez créer une table temporaire pour cela, en boucle sur les résultats (dans une autre FOR
boucle) ou - sans utiliser UNION
- juste revenir dans chaque itération, en fonction de vos besoins.
Et, bien sûr, cela suppose que vous souhaitez sélectionner une colonne unique (ou plusieurs, mais toujours avec le même nom et le même type) de toutes les tables. Si vous avez simplement besoin de toutes les données de chaque table, les tables doivent avoir la même structure (les mêmes types de colonnes dans le même ordre, avec les mêmes noms).
Remarques:
format()
a été introduite dans la version 9.1DO
. Le problème avec c'est que vous ne pouvez pas simplement utiliser SELECT
là-bas pour retourner des lignes, car elle a été signalée dans une autre réponse .OK, il est vraiment en retard, mais j'ai eu le même problème à résoudre et j'ai réussi à le résoudre et retourner toutes les lignes de toutes les tables sous un schéma spécifique à l'aide d'un FUNCTION
comme DO
ne fonctionnait pas pour Moi, malheureusement suggéré des réponses ne fonctionnaient pas vraiment, comme en utilisant DO
ne retournait rien, voici mon FUNCTION
:
CREATE OR REPLACE FUNCTION union_all_tables()
RETURNS TABLE
(
id integer,
full_name varchar(100),
col3 varchar(200),
col4 numeric,
col5 char,
version bigint
) AS
$$
DECLARE
dynamic_query text = '';
r_row record;
BEGIN
FOR r_row IN SELECT table_schema || '.' || table_name qualified_table_name
FROM information_schema.tables
WHERE table_schema = 'staging'
AND table_name LIKE '%_postfix'
LOOP
dynamic_query := dynamic_query || format('UNION SELECT ' ||
'id, ' ||
'full_name, ' ||
'col3, ' ||
'col4, ' ||
'col5, ' ||
'version ' ||
'FROM %s ', r_row.qualified_table_name) || E'\n'; -- adding new line for pretty print, it is not necessary
END LOOP;
-- before we execute the query, we need to remove first "UNION " from the string
dynamic_query := SUBSTRING(dynamic_query, 7) || ';';
-- printing the statement as a notice so you know that the statement is in a good format,
-- or you can copy paste it and try it in the console to know if that statement is working or not.
RAISE NOTICE 'Union all tables in staging, executing statement: %', dynamic_query;
RETURN QUERY EXECUTE dynamic_query;
END;
$$
LANGUAGE plpgsql;
Notez que j'ai ajouté AND table_name LIKE '%_postfix'
Ici si vous avez eu une convention de nommage et que vous souhaitez enregistrer des maux de tête pour cela, si vous ne le voulez pas, supprimez-le, notez également que si vous voulez faire UNION
toutes les tables doivent suivre la même chose. Structure, sinon vous sélectionnez les colonnes communes que vous souhaitez (et ceci est mon cas ici dans ma solution), sinon si vous voulez toutes les colonnes, il a besoin d'un script plus complexe pour cela.
Cette solution travaillant pour moi dans PostgreSQL 10 et 11.