В любом случае вам нужен динамический SQL.
Имя таблицы как заданный параметр
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;
Вызов:
SELECT * FROM foo(456887)
Как правило, вы должны очищать имена таблиц с помощью format ( %I )
, чтобы избежать внедрения SQL. Только с integer
в качестве динамического ввода в этом нет необходимости. Дополнительные сведения и ссылки в этом связанном ответе:
INSERT с именем динамической таблицы в функции триггера
Модель данных
Для модели данных могут быть веские причины. Например, разделение/сегментирование или отдельные привилегии...
Если у вас нет такой веской причины, рассмотрите возможность объединения нескольких таблиц с одинаковой схемой в одну и добавьте столбец number
as. Тогда вам не нужен динамический SQL.
Рассмотрим наследование. Затем вы можете добавить условие для tableoid
, чтобы извлекать строки только из данной дочерней таблицы:
SELECT * FROM parent_table
WHERE tableoid = 'pa456887'::regclass
Однако помните об ограничениях наследования. Связанные ответы:
Имя 2-й таблицы в зависимости от значения в 1-й таблице
Получение имени таблицы соединений из значений в первой таблице динамически усложняет ситуацию.
Всего за несколько столов
LEFT JOIN
каждый по tableoid
. В строке есть только одно совпадение, поэтому используйте 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
Для многих столов
Объедините цикл с динамическими запросами:
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;
person
Erwin Brandstetter
schedule
16.07.2014