【问题标题】:How to give a unique constraint to a combination of a column and a fixed value in Oracle?如何为Oracle中的列和固定值的组合赋予唯一约束?
【发布时间】:2019-12-04 22:59:47
【问题描述】:

我有一个包含 3 列的表: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

【问题讨论】:

  • 用三列创建主键不解决?
  • @Lawrence,创建具有三列的主键将不允许我创建像引用的第一个示例那样的记录。
  • 我认为Oracle不允许您在表中创建布尔列。但是您可以尝试一下:stackoverflow.com/questions/26679831/…
  • 编码 c=true 为 c=0 ,c=false 为 c 0。插入 c 0 为真,sequence.nextval 为假。

标签: sql oracle constraints unique-constraint composite-key


【解决方案1】:

使用基于唯一函数的索引,它只处理带有C = 'true' 的行。

您必须以某种方式组合列 AB - 我使用字符串连接。

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  

【讨论】:

  • 我正要写一些东西,使用虚拟列来存储 TRUE 或 NULL 并将索引基于该列,但这样更简洁。不错!
  • 请原谅,C 列不是布尔值,而是一个数字。但是该命令对我有用。谢谢。
【解决方案2】:

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 有奇怪的设置...

【讨论】:

  • @MarmiteBomber - 您的版本仍然可以使用整数,这就是问题 *8-) 中显示的所有内容
猜你喜欢
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-17
  • 2013-03-25
  • 2020-08-23
相关资源
最近更新 更多