Функция PL / pgSQL для возврата результатов различных запросов SELECT из другой базы данных - PullRequest
0 голосов
/ 04 октября 2018

Я нашел эту очень интересную статью: Рефакторинг функции PL / pgSQL для возврата результатов различных запросов SELECT из Эрвин Брандстеттер , который описывает, как вернуть все столбцы различных таблицтолько с одной функцией:

CREATE OR REPLACE FUNCTION data_of(_table_name anyelement, _where_part text)
  RETURNS SETOF anyelement AS
$func$
BEGIN
   RETURN QUERY EXECUTE 
      'SELECT * FROM ' || pg_typeof(_table_name)::text || ' WHERE ' || _where_part;

END
$func$ LANGUAGE plpgsql;

Вызов:

SELECT * FROM data_of(NULL::tablename,'1=1 LIMIT 1');

Это работает довольно хорошо.Мне нужно очень похожее решение, но для получения данных из таблицы в другой базе данных через dblink .Это означает, что вызов NULL::tablename не удастся, поскольку таблица не существует в базе данных, в которой сделан вызов.Интересно, как заставить это работать.Любая попытка подключиться внутри функции через dblink к другой базе данных не смогла получить результат NULL :: tablename.Кажется, функция polymorph нуждается в параметре polymorph, который создает возвращаемый тип функции неявным образом.

Я был бы очень признателен, если бы кто-нибудь мог мне помочь.

Большое спасибо

С наилучшими пожеланиями, Брайан

1 Ответ

0 голосов
/ 08 октября 2018

кажется, что этот запрос объяснить сложнее, чем я думал.Вот вторая попытка с настройкой теста:

База данных 1

Сначала мы создадим тестовую таблицу с некоторыми данными в базе данных 1:

CREATE TABLE db1_test
(
  id integer NOT NULL,
  txt text
)
WITH (
  OIDS=TRUE
);
INSERT INTO db1_test (id, txt) VALUES(1,'one');
INSERT INTO db1_test (id, txt) VALUES(2,'two');
INSERT INTO db1_test (id, txt) VALUES(3,'three');

Теперь мы создаем функцию полиморфа в базе данных 1:

-- create a polymorph function with a polymorph parameter "_table_name" on database 1
-- the return type is set implicit by calling the function "data_of" with the parameter "NULL::[tablename]" and a where part
CREATE OR REPLACE FUNCTION data_of(_table_name anyelement, _where_part text)
  RETURNS SETOF anyelement AS
$func$
BEGIN
   RETURN QUERY EXECUTE 
      'SELECT * FROM ' || pg_typeof(_table_name)::text || ' WHERE ' || _where_part;

END
$func$ LANGUAGE plpgsql;

Теперь мы делаем тестовый вызов, если все работает в соответствии с аспектами в базе данных 1

SELECT * FROM data_of(NULL::db1_test, 'id=2');

Это работает.Пожалуйста, обратите внимание, я не указываю никаких столбцов таблицы db1_test.Теперь мы переключаемся на базу данных 2.

База данных 2

Здесь мне нужно сделать точно такой же вызов data_of из базы данных 1, как и раньшеи хотя БЕЗ зная столбцы выбранной таблицы во время вызова.К сожалению, это не сработает, работает только один вызов:

SELECT
*
FROM dblink('dbname=[database1] port=[port] user=[user] password=[password]'::text, 'SELECT * FROM data_of(NULL::db1_test, \'id=2\')'::text)
t1(id integer, txt text);

Заключение

Этот вызов работает, но, как вы видите, янужно хотя бы один раз указать, как выглядят все столбцы из таблицы, которую я хочу выбрать.Я ищу какой-нибудь способ обойти это и сделать возможным звонок без знания всех столбцов таблицы в базе данных 1.

Конечная цель

Моя конечная цель - создать функцию в базе данных 2, которая выглядит как

SELECT * from data_of_dblink('table_name','where_part')

и которая вызывает internaly data_of () для database1, чтобы можно было выбрать таблицу в другой базе данных с частью where в качестве параметра,Он должен работать как статический вид, но с возможностью передачи части where в качестве параметра.

Я чрезвычайно открыт для предложений.

Большое спасибо

Брайан

...