Dans tous les cas, vous avez besoin de SQL dynamique.
Nom de la table comme paramètre donné
CREATE OR REPLACE FUNCTION foo(_number int)
RETURNS TABLE (cpa int, nr text, vym text) AS -- adapt to actual data types!
$func$
BEGIN
RETURN QUERY EXECUTE format(
'SELECT t.cpa, substring(t.ku,'[0-9]+'), p.vym
FROM public."table_data_C" t
LEFT JOIN %s p USING (cpa)'
, 'pa' || _number
);
END
$func$ LANGUAGE plpgsql;
Appel :
SELECT * FROM foo(456887)
Généralement, vous désinfectez les noms de table avec le format ( %I )
pour éviter l'injection SQL. Avec juste un integer
comme entrée dynamique qui n'est pas nécessaire. Plus de détails et de liens dans cette réponse connexe :
INSERT avec le nom de la table dynamique dans la fonction de déclenchement
Modèle de données
Il peut y avoir de bonnes raisons pour le modèle de données. Comme le partitionnement/sharding ou les privilèges séparés...
Si vous n'avez pas une si bonne raison, envisagez de consolider plusieurs tables avec un schéma identique en une seule et ajoutez le number
comme colonne. Alors vous n'avez pas besoin de SQL dynamique.
Considérez l'héritage
. Ensuite, vous pouvez ajouter une condition sur tableoid
pour ne récupérer que les lignes d'une table enfant donnée :
SELECT * FROM parent_table
WHERE tableoid = 'pa456887'::regclass
Soyez cependant conscient des limites de l'héritage. Réponses associées :
- Obtenir le nom de la table source d'une ligne lors de l'interrogation du parent dont elle hérite
- Sélectionner (récupérer) tous les enregistrements de plusieurs schémas à l'aide de Postgres
Nom de la 2ème table en fonction de la valeur dans la 1ère table
Dériver le nom de la table de jointure des valeurs de la première table complique dynamiquement les choses.
Pour seulement quelques tables
LEFT JOIN
chacun sur tableoid
. Il n'y a qu'une seule correspondance par ligne, utilisez donc COALESCE
.
SELECT t.*, t.tbl, COALESCE(p1.vym, p2.vym, p3.vym) AS vym
FROM (
SELECT cpa, ('pa' || substring(ku,'[0-9]+'))::regclass AS tbl
FROM public."table_data_C"
-- WHERE <some condition>
) t
LEFT JOIN pa456887 p1 ON p1.cpa = t.cpa AND p1.tableoid = t.tbl
LEFT JOIN pa456888 p2 ON p2.cpa = t.cpa AND p2.tableoid = t.tbl
LEFT JOIN pa456889 p3 ON p3.cpa = t.cpa AND p3.tableoid = t.tbl
Pour de nombreux tableaux
Combinez une boucle avec des requêtes dynamiques :
CREATE OR REPLACE FUNCTION foo(_number int)
RETURNS TABLE (cpa int, nr text, vym text) AS
$func$
DECLARE
_nr text;
BEGIN
FOR _nr IN
SELECT DISTINCT substring(ku,'[0-9]+')
FROM public."table_data_C"
LOOP
RETURN QUERY EXECUTE format(
'SELECT t.cpa, _nr, p.vym
FROM public."table_data_C" t
LEFT JOIN %I p USING (cpa)
WHERE t.ku LIKE (_nr || '%')'
, 'pa' || _nr
);
END LOOP;
END
$func$ LANGUAGE plpgsql;