代码之家  ›  专栏  ›  技术社区  ›  devoured elysium

在Oracle的Check语句中使用子查询

  •  20
  • devoured elysium  · 技术社区  · 14 年前

    所以我试图解决这个问题,但最后一行(检查)似乎不允许在其中进行子查询。有什么方法能让它起作用吗?

    CREATE TABLE Tank (
        n_id            int,
        day             date,
        level           int,
        CONSTRAINT pk_w_td PRIMARY KEY (n_id,day),
        CONSTRAINT fk_w_td_tan FOREIGN KEY (n_id) REFERENCES Tanks ON DELETE CASCADE,
        CHECK (level > 0 AND level <= (SELECT capacity FROM Tanks WHERE Tanks.n_id = TanksDay.n_id))
    );
    

    以下是错误信息:

    Error at Command Line:7 Column:32 Error report: SQL Error: ORA-02251: subquery not allowed here
    02251. 00000 -  "subquery not allowed here"
    *Cause:    Subquery is not allowed here in the statement.
    *Action:   Remove the subquery from the statement.
    
    5 回复  |  直到 14 年前
        1
  •  24
  •   Justin Cave    14 年前

    由于检查约束不能基于查询,有三种基本方法可以解决此类问题。

    选项1:触发器

    选项2:物化视图

    选项3:更改数据模型

    如果表a中的某个值依赖于表B中的某个限制,则可能表示B中的限制应该是表a的一个属性(而不是表B的一个属性或除了表B之外的属性)。当然,这取决于数据模型的具体情况,但通常值得考虑。

        2
  •  7
  •   Tony Andrews    14 年前

    不很遗憾,检查约束不能包含子查询-请参阅 documentation

        3
  •  2
  •   Lukas Eder    7 年前

    您正在寻找的特性称为SQL断言, and it's not yet implemented in Oracle 12c

        4
  •  1
  •   Jeffrey Kemp    14 年前

    贾斯汀的回答有一些好主意。另一种方法是用一个包(TAPI,如果您愿意的话)包装表的所有插入/更新,并在其中实现检查。您需要确保所有应用程序都使用您的TAPI。您还需要实现一些自定义锁定,以保护约束不受并发活动的影响。

        5
  •  0
  •   Markus Winand    14 年前

    您可能需要创建触发器并使用 RAISE_APPLICATION_ERROR