【问题标题】:Create array of custom domain postgres创建自定义域 postgres 数组
【发布时间】:2017-09-01 17:09:22
【问题描述】:

由于枚举的继承限制(您不能从函数内向枚举添加值),我将切换到自定义域,并使用检查约束来验证值。我需要能够创建自定义枚举的数组,但是当我尝试这样的事情时:

CREATE DOMAIN foo AS text CHECK (VALUE IN ('foo', 'bar'));
CREATE TABLE foo_table(foo_column foo[]);

我得到了错误

type "foo[]" does not exist

通过谷歌搜索,我找到了this from 2004,这看起来像是对它的支持。有没有办法做到这一点?

谢谢!

更新

我想出了一个老生常谈的解决方案,如果几天后没有人提出更好的解决方案,我将把它作为答案。此解决方案意味着您不能将类型重用为数组,您必须创建一个单独的类型作为数组:

CREATE DOMAIN foo_group AS text[] CHECK (VALUE <@ ARRAY['foo', 'bar']);

CREATE TABLE foo_table(foo_column foo_group);

以下作品:

INSERT INTO foo_table VALUES(ARRAY['foo']);
INSERT INTO foo_table VALUES(ARRAY['foo', 'bar']);
INSERT INTO foo_table VALUES(ARRAY['bar']);

以下不要:

INSERT INTO foo_table VALUES(ARRAY['foo', 'baz']);
INSERT INTO foo_table VALUES(ARRAY['baz']);

【问题讨论】:

  • CREATE DOMAIN foo_group AS text[] CHECK (VALUE &lt;@ ARRAY['foo', 'bar']); - 没有附加功能。 Doc
  • 太棒了。不知道范围运算符适用于这样的数组
  • 它不是“范围运算符”。对于不同类型的参数,有几个具有相同符号的运算符。在psql中执行\do+ &lt;@
  • 啊,所以arraycontained(left, right) 也可以。在数组函数页面上寻找类似的东西,猜我错过了。

标签: sql postgresql enums


【解决方案1】:

另一种可能的解决方法是:

CREATE TYPE foo_tup AS (item foo);

域类型可以像这样包裹在元组中,这为您提供了一个数组构造函数。缺点是现在您可能想要创建演员表:

select array[row('foo')::foo_tup, row('bar')];

例如,您可以创建一个函数和一个演员:

create function foo_tup(foo) returns foo_tup language sql as $$
    select row($1)::foo_tup;
$$ immutable;
create function foo(foo_tup) returns foo language sql as $$
     select $1.item;
$$;
create cast (foo as foo_tup) with function foo_tup(foo);
create cast (foo_tup as foo) with function foo(foo_tup);

那么聚合就变得简单了:

select array_agg(myfoo::foo_tup) from my_table; 

虽然你得到了额外的括号。

【讨论】:

    猜你喜欢
    • 2011-09-03
    • 2018-07-11
    • 2012-10-02
    • 2018-07-16
    • 2021-01-07
    • 1970-01-01
    • 1970-01-01
    • 2014-06-20
    • 1970-01-01
    相关资源
    最近更新 更多