[英]How to give a unique constraint to a combination of a column and a fixed value in Oracle?
I have a table with with 3 columns: A (number), B (number) and C (boolean).我有一个包含 3 列的表格:A(数字)、B(数字)和 C(布尔值)。
I would need to create a rule that would prevent records from being created with columns A and B and with C equal to true.我需要创建一个规则,以防止使用列 A 和 B 以及 C 等于 true 创建记录。 For example.
例如。
This would be allowed:这将被允许:
A B C
1 2 true
1 2 false
1 2 false
But this, no:但是这个,不:
A B C
1 2 true
1 2 true
1 2 false
Use unique function based index , that process only rows with C = 'true'
.使用基于唯一函数的 index ,仅处理
C = 'true'
。
You must somehow combine the columns A
and B
- I use the string concatenation.您必须以某种方式组合
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
Slight variation on MarmiteBomber's approach, to avoid concatenating the values (which could cause accidental clashes with non-integer values): 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
Quick example of why non-integers (if they can exist) might be a problem:为什么非整数(如果它们可以存在)可能是一个问题的快速示例:
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
... because for both '1.1' ||'.'|| '2'
... 因为对于
'1.1' ||'.'|| '2'
'1.1' ||'.'|| '2'
and '1' ||'.'|| '1.2'
'1.1' ||'.'|| '2'
和'1' ||'.'|| '1.2'
'1' ||'.'|| '1.2'
resolve to the same string, '1.1.2'
. '1' ||'.'|| '1.2'
解析为相同的字符串'1.1.2'
。
This can also be a problem when combining string values rather than numbers.在组合字符串值而不是数字时,这也可能是一个问题。 In either case you can avoid it by using a delimiter which cannot exist in either value;
在任何一种情况下,您都可以通过使用任何一个值中都不能存在的分隔符来避免它; harder to do with strings, but with numbers any punctuation other than a period (or comma to be safe) would probably do - unless someone has a weird setting for
nls_numeric_characters
...处理字符串更难,但对于数字,除了句号(或逗号是安全的)之外的任何标点符号都可能会做 - 除非有人对
nls_numeric_characters
有一个奇怪的设置......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.