在CREATE的CHECK语句中使用SQL聚合函数

时间:2018-01-25 20:52:12

标签: sql postgresql database-design aggregate-functions

在数据库系统设计领域迈出第一步,我的任务是使用PostgreSQL环境准备一个与业余爱好相关的数据库。

我的一张桌子将存储有关可收集棋盘游戏的已发布扩展的一些细节。所述扩展以编号波形一次释放。我希望将波数作为我的表的一列包含在内,并将其限制为一定的限制 - 数字必须为:

  • 正面(> 0);
  • 不大于表中的当前最大值加一(< = MAX()+ 1;

因此,可以将来自单个波的多个扩展插入到表中,并且不能破坏编号波链。我尝试使用CHECK语句设置这些条件

CREATE TABLE Expansions
(
    ID INTEGER NOT NULL,
    Name VARCHAR(50) NOT NULL COLLATE PXW_PLK,
    WaveNumber INTEGER NOT NULL,
    ReleaseDate DATE NOT NULL,
    CONSTRAINT Expansions_PK PRIMARY KEY (ID),
    CONSTRAINT Expansions_U UNIQUE (Name),
    CONSTRAINT Expansions_WaveNumber CHECK (WaveNumber BETWEEN 1 and MAX(WaveNumber) + 1)
);

但这种方法导致异常

Message: isc_dsql_prepare failed

SQL Message : -104
Invalid token

Engine Code    : 335544569
Engine Message :
Dynamic SQL Error
SQL error code = -104
Invalid aggregate reference

我很难确定是否:

  • 我的方法完全错误并强制执行我对不同SQL构造的限制调用?
  • 我无法在CHECK语句中适当地放置MAX()调用?

1 个答案:

答案 0 :(得分:1)

首先,check约束不直接支持。

其次,可能有一个单独的WaveNumbers表和一个串行列将是最好的解决方案。您可以拥有外键约束。这并不能保证没有差距。它确实保证波数是“有效的”。

Postgres确实提供了解决方案。您可以创建用于执行验证的用户定义函数,然后在check约束中使用此函数。

我不推荐这种方法。在检查约束中聚合函数有很多开销。并且,我怀疑对数据模型的一些调整将允许您使用外键约束。