如何在两列上独立制作唯一约束顺序
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_one
和 point_two
的数据类型与 Oracle greatest
和 least
函数兼容。如果没有,您需要一个自己的函数来为您的复杂数据类型选择 "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 约束,但我还没有决定它是否可行。
我正在使用 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_one
和 point_two
的数据类型与 Oracle greatest
和 least
函数兼容。如果没有,您需要一个自己的函数来为您的复杂数据类型选择 "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 约束,但我还没有决定它是否可行。