Моя база данных использует схемы Postgres для предоставления отдельной, многопользовательской среды для пользователей. Каждая схема имеет копию тех же таблиц.Добавить имя схемы в динамический запрос Postgres
У меня есть один конкретный запрос, где мне нужно присоединиться к схемам, вернуть список записей (в этом случае children
). У меня это работает с помощью динамического SQL-запроса, как показано ниже. Тем не менее, я хочу добавить в столбец каждый результат, который указывает имя схемы, из которой пришел эта строка.
Текущий динамический запрос
(вид Schema как: OPERATOR_SCHEMA_my-great-company
)
CREATE OR REPLACE FUNCTION all_children_dynamic() RETURNS SETOF children AS $$
DECLARE
schema RECORD;
BEGIN
FOR schema IN EXECUTE
format(
'SELECT schema_name FROM information_schema.schemata WHERE left(schema_name, 16) = %L',
'OPERATOR_SCHEMA_'
)
LOOP
RETURN QUERY EXECUTE
format('SELECT * FROM %I.children', schema.schema_name);
END LOOP;
END;
$$ LANGUAGE plpgsql;
--------
-- Usage: SELECT "id", "name" FROM all_children_dynamic();
Это возвращает что-то вроде:
-------------
| id | name |
| 1 | Bob |
| 2 | Joe |
-------------
В то время как я хотел его вернуть что-то например:
-------------------------------
| id | name | schema_name |
| 1 | Bob | darcy's-store |
| 2 | Joe | bob's-4th-store |
-------------------------------
Следует отметить, что имена схем определены пользователем и могут содержать в себе кавычки.
Как добавить в соответствующее имя схемы для каждого ребенка?
Я попробовал несколько вариантов следующее:
LOOP
RETURN QUERY EXECUTE
format('SELECT %s AS schema_name, * FROM %1$I.children', schema.schema_name);
END LOOP;
Но у меня возникают некоторые проблемы с форматированием и т.д. Там, вероятно, некоторые quote_X
функциональность, я должен использовать здесь.
Я не очень осведомлен о Postgres (и базы данных в целом), поэтому ваше терпение ценится!
ОБНОВЛЕНИЕ
Ниже приведены точные ошибки я получаю несколько вариаций.
Input:
format('SELECT %s AS schema_name, * FROM %1$I.children', schema.schema_name);
ERROR: column "operator_schema_don" does not exist
LINE 1: SELECT OPERATOR_SCHEMA_don-t-display-data AS schema_name, * ...
QUERY: SELECT OPERATOR_SCHEMA_don-t-display-data AS schema_name, * FROM "OPERATOR_SCHEMA_don-t-display-data".children
Input:
format('SELECT %s AS schema_name, * FROM %I.children', quote_literal(schema.schema_name), schema.schema_name);
ERROR: structure of query does not match function result type
DETAIL: Returned type unknown does not match expected type uuid in column 1.
UPDATE 2
Я все ближе, но не совсем там еще.
CREATE OR REPLACE FUNCTION all_children_dynamic() RETURNS TABLE (id uuid, schema_name varchar) AS $$
DECLARE
schema RECORD;
BEGIN
FOR schema IN EXECUTE
format(
'SELECT schema_name FROM information_schema.schemata WHERE left(schema_name, 16) = %L',
'OPERATOR_SCHEMA_'
)
LOOP
RETURN QUERY EXECUTE
format('SELECT id, %L AS schema_name FROM %I.children', quote_literal(schema.schema_name), schema.schema_name);
END LOOP;
END;
$$ LANGUAGE plpgsql;
ERROR: structure of query does not match function result type
DETAIL: Returned type unknown does not match expected type character varying in column 2.
CONTEXT: PL/pgSQL function all_children_dynamic() line 11 at RETURN QUERY
Почему тип возврата возвращается как неизвестный? Я ожидал, что это будет вставка строки и просто возврат этого типа.
Какая именно ошибка вы получаете? Поскольку вы добавляете новый столбец (в этом случае имя схемы) к вашему запросу, результат функции не является набором детей. Правильно? Поэтому вам может потребоваться посмотреть тип возвращаемого типа, как указано [здесь] (http://www.postgresql.org/docs/9.4/static/sql-createfunction.html) – cableload
@cableload Я добавил два примера ошибок, которые я получил с что я пытался. Имейте в виду, я понятия не имею, что я делаю :) – Brandon
, как вы можете видеть по ошибке, вы не можете вернуть SETOF Children, поскольку вы добавляете другой столбец. Попробуйте вернуть таблицу всех столбцов, которые вы должны вернуть. Ваш синтаксис SQL выглядит хорошо для меня. – cableload