【问题标题】:Oracle SQL Constraint where clauseOracle SQL 约束 where 子句
【发布时间】:2023-04-03 19:15:01
【问题描述】:

我在 oracle 上有表 Tester,其中包含以下列:

  • 测试者ID
  • 测试人员姓名
  • 是默认值
  • Application_ID

TesterID 是主键。 现在我希望只能有一个 Default Tester,这意味着只有一个 Tester 可以在 ApplicationID 上拥有 IsDefault =Y 的值。

我尝试了一个约束:

alter table Tester add constraint Tester_ISDEFAULT UNIQUE(IsDefault,Application_ID);

是否可以在 where isdefault= Y 上设置唯一键?

感谢您的帮助!

【问题讨论】:

    标签: sql oracle constraints where clause


    【解决方案1】:

    没有UNIQUE 约束。但是,您可以改用UNIQUE INDEX

    CREATE UNIQUE INDEX ApplicationId_Default_Y ON tester (
      CASE WHEN IsDefault = 'Y'
           THEN ApplicationId
           ELSE NULL
      END
    );
    

    这是一个DEMO

    【讨论】:

    • 你好,它有效,但我不知道如何。您将 IsDefault 设为索引?那么 applicationid 和 else null 是什么意思?
    • 基本上,当IsDefault = 'Y' 时,您将其应用程序ID 存储在索引中。因此,由于它是一个 唯一 索引,如果您尝试使用IsDefault = Y 在索引中再次插入相同的应用程序 id,它将引发异常(因为该应用程序 id 已经在索引中)。
    • 只是扩展 Joao 的解释——这通常被称为“基于函数的索引”。它利用了这样一个事实,即如果整个键为 NULL,Oracle 不会在索引中存储任何内容;所以这个索引只在 IsDefault = 'Y' 时存储 ApplicationId。此外,它是一个唯一索引,因此它保证对于 IsDefault = 'Y' 的任何给定 ApplicationId 只有一行。
    【解决方案2】:

    在测试器上创建唯一索引 tester_ui_1(decode(is_default, 'Y', 0, tester_id), application_id)

    【讨论】:

      【解决方案3】:

      您可以使用基于函数的唯一索引来做到这一点,而不是这样的约束:

      create unique index tester_isdefault on tester 
        (case when isdefault='Y' then application_id end);
      

      由于 Oracle 不会为全为空的键创建索引条目,因此只有 isdefault='Y' 的行才会出现在索引中。

      【讨论】:

        【解决方案4】:

        该约束不起作用,因为这意味着每个 Application_ID 只能有两行 - 一行 IsDefault=0,另一行 IsDefault=1。

        您可以使用触发器强制执行此逻辑。或者,为什么不在您的应用程序逻辑中强制执行它?

        【讨论】:

        • 使用你面临突变错误的触发器,否则你必须发明一种技巧来打败它。如此独特的联邦调查局
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-24
        相关资源
        最近更新 更多