我在PostgreSQL上有一个枚举类型,我想创建一个视图,每个枚举值都有一列。
我的用例类似于这个question。我有一个jsonb列,我想变成一个视图,其中的列由json blob的键组成。我的不同之处在于有效密钥是在枚举中定义的,而不是从对象本身聚合而来。
以下SQL语句基本上是我想要做的,但不起作用:
SELECT json_populate_record(null::activity_type_enum, activities) from some_table;
有没有办法将枚举类型转换为json_populate_record
的第一个参数所期望的类型?
这需要一些动态SQL。
假设视图中的所有列都应具有text
类型。
enum_range()
将枚举成员作为数组,并使用unnest()
将它们转换为集合。' text'
并使用string_agg()
构建逗号分隔的列表。像这样,我们得到一个列定义。CREATE VIEW
语句,从表横向交叉连接json_to_record()
选择我们建立的列定义。CREATE VIEW
执行EXECUTE
语句。我们一起得到以下DO
块:
DO
$$
BEGIN
EXECUTE '
CREATE VIEW some_view
AS
SELECT x.*
FROM some_table t
CROSS JOIN LATERAL json_to_record(t.activities) x(' || (SELECT string_agg(un.m || ' text', ', ')
FROM unnest(enum_range(NULL::activity_type_enum)) un(m)) || ');
';
END;
$$
LANGUAGE plpgsql;
如果json_to_record()
的类型是jsonb_to_record()
而不是activities
,则用jsonb
替换json
。
但是,如果枚举更改,则必须重新运行DO
块,以使视图反映更改。