De cualquier manera, necesita SQL dinámico.
Nombre de tabla como parámetro dado
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;
Llamar:
SELECT * FROM foo(456887)
En general, desinfectaría los nombres de las tablas con format ( %I )
para evitar la inyección SQL. Con solo un integer
como entrada dinámica que no es necesaria. Más detalles y enlaces en esta respuesta relacionada:
INSERTAR con el nombre de la tabla dinámica en la función de activación
Modelo de datos
Puede haber buenas razones para el modelo de datos. Como partición/fragmentación o privilegios separados...
Si no tiene una razón tan buena, considere consolidar varias tablas con un esquema idéntico en una sola y agregue el number
como columna. Entonces no necesita SQL dinámico.
Considere herencia
. Luego puede agregar una condición en tableoid
para recuperar solo filas de una tabla secundaria dada:
SELECT * FROM parent_table
WHERE tableoid = 'pa456887'::regclass
Sin embargo, tenga en cuenta las limitaciones de la herencia. Respuestas relacionadas:
- Obtener el nombre de la tabla de origen de una fila al consultar el padre del que hereda
- Seleccionar (recuperar) todos los registros de múltiples esquemas usando Postgres
Nombre de la segunda tabla según el valor de la primera
Derivar el nombre de la tabla de combinación a partir de los valores de la primera tabla complica las cosas dinámicamente.
Solo para unas pocas mesas
LEFT JOIN
cada uno en tableoid
. Solo hay una coincidencia por fila, así que use 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
Para muchas mesas
Combine un bucle con consultas dinámicas:
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;