【问题标题】:Using SQL aggregate functions within CREATE's CHECK statement在 CREATE 的 CHECK 语句中使用 SQL 聚合函数
【发布时间】:2018-01-25 20:52:12
【问题描述】:

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

我的一张表将存储有关可收藏棋盘游戏已发布扩展包的一些详细信息。所述扩展以编号的波浪形式发布,一次发布几个。我想将波数作为我的表格的一列,并有一定的限制 - 数字必须是:

  • 正数(>0);
  • 不大于表中找到的当前最大值加一 (

因此,来自单个波的多个扩展可以插入到表中,并且编号波链不会被破坏。我尝试使用 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() 调用?

【问题讨论】:

    标签: sql postgresql database-design aggregate-functions


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 谢谢!由于我被要求不要使用冗余的整数字典不必要地增加我的项目的大小,并且用户定义的函数超出了我正在处理的范围,所以现在,我将满足于为此放弃间隙验证在这个阶段的领域。也许在未来,我会回到主题,看看当真正需要时如何实现这样的约束,这里有我的想法更好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-16
    相关资源
    最近更新 更多