【问题标题】:Unique constraint on any combination of two columns对两列任意组合的唯一约束
【发布时间】:2018-06-28 12:25:02
【问题描述】:

我正在尝试为两列的组合实现唯一约束。我正在运行 oracle 11g。

具体来说,我有两列 A 和 B。

我有如下一行

A     B
1     2

那么我希望以下组合在插入时失败

A     B
1     2
2     1

这可以通过 Oracle 中的唯一索引来实现吗?

【问题讨论】:

    标签: sql database oracle oracle11g


    【解决方案1】:

    是的,有可能(例如使用生成的列):

    CREATE TABLE tab(A INT NOT NULL, B INT NOT NULL);
    
    ALTER TABLE tab ADD c1 AS (LEAST(A,B));
    ALTER TABLE tab ADD c2 AS (GREATEST(A,B));
    CREATE UNIQUE INDEX UQ_tab ON tab(c1,c2);
    

    如果需要,您可以隐藏这些列(Oracle 12c):

    ALTER TABLE tab MODIFY c1 INVISIBLE;
    ALTER TABLE tab MODIFY c2 INVISIBLE;
    

    DBFiddle Demo

    编辑:

    更简单的方法:

    CREATE UNIQUE INDEX UQ_tab ON tab(least(A,B), greatest(A,B));
    

    DBFiddle Demo

    【讨论】:

    • @wolφi 失败时的具体例子,请。计算列。
    • 哦,我明白了。我认为“始终生成”或“虚拟”是强制性的,但事实并非如此。
    • 如果列值之一是NULL,则此方法不起作用。
    • @MT0 谢谢,我假设这两列都不能为空。但我看到你用 COALESCE 扩展了我的 anwser,所以我会保持原样。
    • 感谢 Lukasz,这回答了我的问题。 MT0 也提出了一个很好的观点,但我的列已经被标记为不可为空,所以这对我有用。
    【解决方案2】:

    您可以将UNIQUE INDEXLEASTGREATESTCOALESCE 函数一起使用:

    CREATE TABLE table_name (
      a INT,
      b INT
    );
    
    CREATE UNIQUE INDEX table_name__a__b__u ON TABLE_NAME(
      COALESCE( LEAST( a, b ), a, b ),
      GREATEST( a, b )
    );
    

    您需要包含COALESCE,以防其中一个值为NULL

    DBFiddle

    INSERT INTO table_name ( a, b ) VALUES ( 1, 2 );
    1 rows affected
    INSERT INTO table_name ( a, b ) VALUES ( 3, NULL );
    1 rows affected
    INSERT INTO table_name ( a, b ) VALUES ( 2, 1 );
    ORA-00001: unique constraint (SCHEMA_NAME.TABLE_NAME__A__B__U) violated
    INSERT INTO table_name ( a, b ) VALUES ( NULL, 3 );
    ORA-00001: unique constraint (SCHEMA_NAME.TABLE_NAME__A__B__U) violated
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-17
      • 2020-01-06
      • 1970-01-01
      • 1970-01-01
      • 2013-03-25
      • 2017-04-23
      • 2020-10-12
      • 1970-01-01
      相关资源
      最近更新 更多