Как вернуть данные другой таблицы на основе идентификатора, переданного в функцию SQL - PullRequest
0 голосов
/ 17 апреля 2020

Основываясь на этом вопросе Я хотел бы знать, возможно ли вернуть разные данные таблицы на основе идентификатора, переданного функции. Нечто подобное (псевдокод):

CREATE FUNCTION schemaB.testFunc(p_id INT, select_param INT)
  RETURNS setof  schemaZ.Table_1
AS
$$
CASE
    WHEN select_param = 1 THEN SELECT * FROM schemaZ.Table_1 WHERE id = p_id
    WHEN select_param = 2 THEN SELECT * FROM schemaZ.Table_2 WHERE id = p_id
END;
$$
language sql;

Table_1 и Table_2 не имеют одинаковых столбцов, и это делает недействительным указанное выше условие RETURNS.

1 Ответ

1 голос
/ 18 апреля 2020

Это обычно невозможно с SQL функциями . Даже с типом возврата polymorphi c фактический тип возврата должен быть определен во время вызова. Но все операторы в функции SQL планируются до ее выполнения. Таким образом, вы всегда получите сообщение об ошибке для одного из операторов SELECT, возвращающего данные, которые не соответствуют типу возвращаемого значения.

То же самое можно сделать с динамическим c SQL в функции PL / pg SQL - с некоторыми хитростями:

CREATE OR REPLACE FUNCTION f_demo(_tabletype anyelement, _id int)
  RETURNS SETOF anyelement LANGUAGE plpgsql AS
$func$
BEGIN
   RETURN QUERY EXECUTE
      format('SELECT * FROM %s WHERE id = $1', pg_typeof(_tabletype))
   USING  _id;
END
$func$;

Вызов (важно!):

SELECT * FROM f_demo(null::schemaZ.Table_1, 1);

«хитрость» заключается в приведении значения null к нужному типу таблицы, тем самым определяя тип возврата и , выбирая из какой таблицы выбрать. Подробное объяснение:

Примите это как доказательство концепции. Как правило, существуют лучшие (более безопасные, менее запутанные, более производительные) решения ...

Связанные:

...