sql - Oracle数据库中的null等于null吗?
问题描述
我试图使用 Oracle 中的唯一索引强制每个客户端只使用一部活动电话,但无法使其正常工作。这在 PostgreSQL 和 DB2 中完美运行,但在 Oracle 中似乎不起作用。
这是示例:
create table phone (
client_id number(6) not null,
active number(1) not null check (active in (0, 1)),
value varchar2(15)
);
insert into phone (client_id, active, value) values (10, 0, '1111');
insert into phone (client_id, active, value) values (10, 1, '3333');
insert into phone (client_id, active, value) values (15, 0, '5555');
insert into phone (client_id, active, value) values (15, 1, '6666');
insert into phone (client_id, active, value) values (15, 0, '7777'); -- offending row
当我尝试创建索引时:
create unique index ix1 on phone (client_id, case when active = 1 then active end);
似乎Oracle不喜欢它,因为重复的索引条目:
错误:ORA-01452:无法创建唯一索引;发现重复键
SQLState: 72000
如果我删除了有问题的数据行,则可以创建索引。
解决方案
您可以使用:
create unique index ix1 on phone (case active when 1 then client_id end);
sqlfiddle在这里
当所有列都为;时,UNIQUE
索引不会存储行。但是,在您的情况下,基于函数的索引会产生两个值之一,因此该行将被索引,这将导致索引中出现重复值。NULL
NULL
更改它以使输出是从active
和client_id
列派生的单个值意味着active = 0
将导致表达式NULL
输出的CASE
行并且这些行不会包含在索引中,并且只会检查活动行的重复项。
来自 Oracle Unique 约束文档:
为了满足唯一约束,表中的任何两行都不能具有相同的唯一键值。但是,由单个列组成的唯一键可以包含空值。为了满足复合唯一键,表或视图中的任何两行都不能在键列中具有相同的值组合。在所有键列中包含空值的任何行都会自动满足约束。但是,包含一个或多个键列的空值以及其他键列的相同值组合的两行违反了约束。
推荐阅读
- flutter - 什么时候使用'()=>'?
- javascript - 使用自己的键将两个数组对象合并为一个
- python - 试图用python ctypes打开一个用c编写的dll并在其中运行函数,但它以int形式出现,而不是字符串
- arrays - JOLT 数组转换:在列表中的所有对象中添加键
- node.js - 由于文件锁定,jenkins 上的 npm 安装失败
- php - PHP + Xdebug + PhpStorm - 监听不起作用
- azure - 如何更改 Azure Data Studio 结果网格中文本和边框的颜色?
- token - Solidity 库 openzeppelin-solidity/contracts/utils/Context.sol:15:1: ParserError: Expected pragma, abstract contract Context { ^------^
- android - 如何将 android 应用程序移至新的发布者名称?
- vb.net - 是否可以使用循环/if 将 Char 更改为字符串