是否可以在Postgres中创建代数数据类型,然后将其用作列类型?
例如:
CREATE TYPE hoofed AS ENUM('horse', 'goat');
CREATE TYPE monkey AS ENUM('chimp','macaque');
CREATE TYPE ANIMAL AS ENUM(hoofed, monkey);
这失败了:
syntax error at or near "hoofed"
LINE 1: CREATE TYPE ANIMAL AS ENUM(hoofed, monkey);
是否可以做这样的事情?
最终,我希望能够做到的是:
CREATE TABLE zoo (
a ANIMAL,
name text
);
INSERT INTO zoo(a, name) VALUES('horse', 'bob');
INSERT INTO zoo(a, name) VALUES('macaque', 'jimmy');
并且两个记录都是独立有效的。
编辑:@ Abihabi87&#em>下面的回复确实允许我创建一个产品类型,但它仍然不允许我根据需要创建一个联合类型。答案 0 :(得分:6)
您无法从其他枚举类型创建类型枚举:
您可以创建类似于:
的ANIMALCREATE TYPE ANIMAL AS (h hoofed,m monkey);
使用示例:
CREATE TABLE your_table
(
a ANIMAL
);
INSERT INTO your_table(a) select (select ('horse','macaque')::ANIMAL);
答案 1 :(得分:2)
使用功能:
create or replace function create_enum(name, variadic regtype[])
returns void language plpgsql as $$
begin
execute format(
'create type %I as enum(%s)',
$1,
string_agg(quote_literal(enumlabel), ',' order by enumtypid, enumsortorder))
from pg_enum
where enumtypid = any($2);
end $$;
将新类型的名称和枚举类型列表作为参数传递:
select create_enum('animal', 'hoofed', 'monkey');
select enum_range(null::animal) as animal;
animal
----------------------------
{horse,goat,chimp,macaque}
(1 row)
答案 2 :(得分:1)
实际上,您正在尝试合并两种enum
类型
有一些悬而未决的问题:
enum
类型hoofed
的更改不会在以后更改类型animal
)或动态(相反)。< / LI>
enum
种类型或更多?animal
中元素的顺序是什么? 假设 没有重复项,静态设计,两种enum
类型,附加元素的现有顺序以及一次性操作。
您可以使用内置enum support function enum_range(anyenum)
获取给定enum
类型的所有元素的数组。
DO
$$
BEGIN
EXECUTE (
SELECT 'CREATE TYPE animal AS ENUM ('
|| array_to_string(enum_range(null::hoofed)::text[]
|| enum_range(null::monkey)::text[], ''',''')
|| ''')'
);
END
$$;
答案 3 :(得分:1)
使用ENUM
类型,您无法实现动态类型合成/联合。但是,使用DOMAIN
types,您可以实现类似的目标:
create function valid_any_domain(anyelement, variadic regtype[])
returns boolean
language plpgsql
immutable
as $func$
declare
t regtype;
begin
foreach t in array $2 loop
begin
execute format('select $1::%s', t) using $1;
exception
when not_null_violation or check_violation then
continue;
end;
return true;
end loop;
return false;
end;
$func$;
create domain hoofed as text
check (value in ('horse', 'goat'));
create domain monkey as text
check (value in ('chimp','macaque'));
create domain animal as text
check (valid_any_domain(value, 'hoofed', 'monkey'));
更改基类型也会动态更改复合/联合类型,但仍需要手动约束验证(尤其是当从有效频谱中删除某些值时):
alter domain hoofed drop constraint hoofed_check;
alter domain hoofed add check (value in ('horse', 'goat', 'zebra'));
alter domain animal validate constraint animal_check;
http://rextester.com/MBVC62095
注意:但是,对于DOMAIN
类型,您将失去ENUM
属性:自定义排序。 DOMAIN
将始终使用基础类型的排序。