我的数据库使用Postgres模式为用户提供分离的多租户环境。每个模式都有相同表格的副本。将模式名称添加到动态Postgres查询
我有一个特定的查询,我需要跨模式连接,返回记录列表(在这种情况下,children
)。我通过一个动态的SQL查询来完成这个工作,如下所示。但是,我想在列中添加每个指定行来自的模式的名称的结果。
当前动态查询
(架构的样子: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.
更新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儿童,因为你正在添加另一列。尝试返回预期返回的所有列的表格。你的SQL语法对我来说很好。 – cableload