如何在两列上独立制作唯一约束顺序

How can I make a unique constraint order independently on two columns

我正在使用 Oracle 数据库,我需要创建一个如下所示的 table。

MAP(Point_One, Poin_Two, Connection_weight).

table 表示有关图表的数据。我想创建一个带有约束的 table 以防止插入已存在的连接。

例如,table 已经包含此连接:

Point_One | Point_Two | Connection_weight
-----------------------------------------
p_no1     | p_no2     | 10

并且约束会阻止重复插入此连接,即使我尝试以不同的顺序添加点。 (例如: (p_no2, p_no1, 10) )

不幸的是,一个简单的 UNIQUE (Point_One, Point_Two) 约束是不够的。你有什么建议吗?

您可以创建基于函数的索引

CREATE UNIQUE INDEX idx_unique_edge
    ON map( greatest( point_one, point_two ),
            least( point_one, point_two ) );

我假设 point_onepoint_two 的数据类型与 Oracle greatestleast 函数兼容。如果没有,您需要一个自己的函数来为您的复杂数据类型选择 "greatest" 和 "least" 点。

您可以使用触发器轻松实现所需的结果。

 create table map (point_one number, point_two number, connection_weight number)
/
 create or replace trigger tr_map before insert on map
 for each row
 declare
 c number;
   begin
     select count(1) into c from map where (point_one=:new.point_one and   point_two=:new.point_two)
     or
     (point_one=:new.point_two and point_two=:new.point_one);
     if c>0 then
     raise_application_error(-20000,'Connection line already exists');
  end if;
end;
  /

SQL> 插入映射值 (1,2,10);

创建了 1 行。

SQL> 插入映射值 (2,1,10); 插入地图值 (2,1,10) * 第 1 行的错误: ORA-21000: raise_application_error of -100 的错误编号参数超出 范围 ORA-06512: 在 "C##MINA.TR_MAP",第 10 行 ORA-04088: 执行触发器时出错 'C##MINA.TR_MAP'

我还在考虑 CHECK 约束,但我还没有决定它是否可行。