Oracle中如何给列和固定值的组合赋予唯一约束?
How to give a unique constraint to a combination of a column and a fixed value in Oracle?
我有一个包含 3 列的 table:A(数字)、B(数字)和 C(布尔值)。
我需要创建一个规则来防止创建列 A 和 B 以及列 C 等于 true 的记录。例如。
这是允许的:
A B C
1 2 true
1 2 false
1 2 false
但是这个,没有:
A B C
1 2 true
1 2 true
1 2 false
使用基于唯一函数的索引,仅处理具有C = 'true'
.
的行
您必须以某种方式组合列 A
和 B
- 我使用字符串连接。
create unique index uq_true on test(case when c = 'true' then a||'.'||b end);
insert into test(a,b,c) values (1,2,'true');
insert into test(a,b,c) values (1,2,'false');
insert into test(a,b,c) values (1,2,'false');
insert into test(a,b,c) values (1,2,'true');
ORA-00001: unique constraint (DWH.UQ_TRUE) violated
select * from test;
A B C
---------- ---------- ----------
1 2 true
1 2 false
1 2 false
MarmiteBomber 方法的细微变化,以避免连接值(这可能会导致与非整数值的意外冲突):
create table t (a number, b number, c varchar2(5),
constraint t_chk check (c in ('true', 'false'))
);
create unique index t_unq
on t (case when c = 'true' then a end, case when c = 'true' then b end);
insert into t(a,b,c) values (1,2,'true');
1 row inserted.
insert into t(a,b,c) values (1,2,'false');
1 row inserted.
insert into t(a,b,c) values (1,2,'false');
1 row inserted.
insert into t(a,b,c) values (1,2,'true');
ORA-00001: unique constraint (MY_SCHEMA.T_UNQ) violated
select * from t;
A B C
---------- ---------- -----
1 2 true
1 2 false
1 2 false
为什么非整数(如果它们可以存在)可能是一个问题的快速示例:
create unique index uq_true on test(case when c = 'true' then a||'.'||b end);
insert into test(a,b,c) values (1.1, 2,'true');
1 row inserted.
insert into test(a,b,c) values (1, 1.2,'true');
ORA-00001: unique constraint (MY_SCHEMA.UQ_TRUE) violated
select * from test;
A B C
---------- ---------- -----
1.1 2 true
... 因为对于 '1.1' ||'.'|| '2'
和 '1' ||'.'|| '1.2'
都解析为相同的字符串,'1.1.2'
.
在组合字符串值而不是数字时,这也可能是一个问题。在任何一种情况下,您都可以通过使用在任何一个值中都不能存在的定界符来避免它;更难处理字符串,但对于数字,除了句点(或安全的逗号)之外的任何标点符号都可能会这样做 - 除非有人对 nls_numeric_characters
...
进行了奇怪的设置
我有一个包含 3 列的 table:A(数字)、B(数字)和 C(布尔值)。
我需要创建一个规则来防止创建列 A 和 B 以及列 C 等于 true 的记录。例如。
这是允许的:
A B C
1 2 true
1 2 false
1 2 false
但是这个,没有:
A B C
1 2 true
1 2 true
1 2 false
使用基于唯一函数的索引,仅处理具有C = 'true'
.
您必须以某种方式组合列 A
和 B
- 我使用字符串连接。
create unique index uq_true on test(case when c = 'true' then a||'.'||b end);
insert into test(a,b,c) values (1,2,'true');
insert into test(a,b,c) values (1,2,'false');
insert into test(a,b,c) values (1,2,'false');
insert into test(a,b,c) values (1,2,'true');
ORA-00001: unique constraint (DWH.UQ_TRUE) violated
select * from test;
A B C
---------- ---------- ----------
1 2 true
1 2 false
1 2 false
MarmiteBomber 方法的细微变化,以避免连接值(这可能会导致与非整数值的意外冲突):
create table t (a number, b number, c varchar2(5),
constraint t_chk check (c in ('true', 'false'))
);
create unique index t_unq
on t (case when c = 'true' then a end, case when c = 'true' then b end);
insert into t(a,b,c) values (1,2,'true');
1 row inserted.
insert into t(a,b,c) values (1,2,'false');
1 row inserted.
insert into t(a,b,c) values (1,2,'false');
1 row inserted.
insert into t(a,b,c) values (1,2,'true');
ORA-00001: unique constraint (MY_SCHEMA.T_UNQ) violated
select * from t;
A B C
---------- ---------- -----
1 2 true
1 2 false
1 2 false
为什么非整数(如果它们可以存在)可能是一个问题的快速示例:
create unique index uq_true on test(case when c = 'true' then a||'.'||b end);
insert into test(a,b,c) values (1.1, 2,'true');
1 row inserted.
insert into test(a,b,c) values (1, 1.2,'true');
ORA-00001: unique constraint (MY_SCHEMA.UQ_TRUE) violated
select * from test;
A B C
---------- ---------- -----
1.1 2 true
... 因为对于 '1.1' ||'.'|| '2'
和 '1' ||'.'|| '1.2'
都解析为相同的字符串,'1.1.2'
.
在组合字符串值而不是数字时,这也可能是一个问题。在任何一种情况下,您都可以通过使用在任何一个值中都不能存在的定界符来避免它;更难处理字符串,但对于数字,除了句点(或安全的逗号)之外的任何标点符号都可能会这样做 - 除非有人对 nls_numeric_characters
...