具有三列但只有一行可以等于某个值的Oracle约束

这听起来可能很容易,也可能是。我有3列,一列有一个常量字符串(Name),一列(Status)有两个选项(外键),另一列(Room_Id)是另一个表的父键,如何才能确保只有一行设置为同一名称的&on";值。不能有多行的";on";值具有相同的名称,但可以有多行的";Off";值具有相同的名称。示例。

room_id       name       status
1             daniel       ON   --- OK for only one ON to be set for daniel
2             daniel       OFF
3             daniel       OFF
4             daniel       OFF
5             daniel       OFF
6             daniel       ON  --- THIS IS NOT ALLOWED...  but everything is UNIQUE
1             jeff         OFF
2             jeff         OFF
3             jeff         ON  --- OK for only ONE to be set to "ON" for jeff.
4             jeff         ON  --- THIS IS NOT ALLOWED... the room_id keeps things UNIQUE
5             jeff         ON  --- THIS IS NOT ALLOWED...

下面的唯一约束允许多个";on";值具有相同的名称。

ADD CONSTRAINT constratin_name_uq UNIQUE (room_id, name, status)
我认为我还需要一个检查约束,但在状态列WHERE VALUE=‘ON’上的计数不大于1...要确保只有一个";名称";和";状态";的值为...

下面的约束不允许有多个&Quot;Off&Quot;值,这在我的案例中是必需的。

ADD CONSTRAINT constraint_name_uq UNIQUE (name, status)

还有...所有名称都可以是";Off;,但对于每个给定的名称,只能有一个";On。

感谢您的帮助

谢谢, 丹尼尔


解决方案

您可以创建唯一索引:

CREATE UNIQUE INDEX table_name__status_name__u
  ON table_name( CASE status WHEN 'ON' THEN name END );

表中的哪个:

CREATE TABLE table_name (
  room_id NUMBER
          NOT NULL,
  name    VARCHAR2(10)
          NOT NULL,
  status  VARCHAR2(3)
          NOT NULL
          CHECK ( STATUS IN ( 'ON', 'OFF' ) )
);

这样就行了:

INSERT INTO table_name ( room_id, name, status )
SELECT 1, 'alice', 'ON' FROM DUAL UNION ALL
SELECT 2, 'alice', 'OFF' FROM DUAL UNION ALL
SELECT 3, 'alice', 'OFF' FROM DUAL UNION ALL
SELECT 4, 'alice', 'OFF' FROM DUAL UNION ALL
SELECT 5, 'alice', 'OFF' FROM DUAL UNION ALL
SELECT 6, 'alice', 'OFF' FROM DUAL UNION ALL
SELECT 1, 'beatrice', 'OFF' FROM DUAL UNION ALL
SELECT 2, 'beatrice', 'OFF' FROM DUAL UNION ALL
SELECT 3, 'beatrice', 'OFF' FROM DUAL;

然而,这:

INSERT INTO table_name ( room_id, name, status )
SELECT 7, 'alice', 'ON' FROM DUAL;

失败,错误为:

ORA-00001: unique constraint (FIDDLE_XFKAWDIVOXGJZVQESSZQ.TABLE_NAME__STATUS_NAME__U) violated

此操作也失败,但出现相同的异常:

INSERT INTO table_name ( room_id, name, status )
SELECT 4, 'beatrice', 'ON' FROM DUAL UNION ALL
SELECT 5, 'beatrice', 'ON' FROM DUAL;

小提琴here

相关文章