我想咨询/收集一些关于oracle中可空列的唯一约束定义的可能解决方案的想法。
我们有一个客户表
+---+-----------+-----------+-----------+ |ID |FIRST_NAME |LAST_NAME |EXT_CODE | +---+-----------+-----------+-----------+ |1 |Peter |Pletan |ABC | |2 |John |Dollar |DEF | |3 |Mia |Zin |GHI | |4 |Jasper |Blau |NULL | |5 |George |Khan |NULL | -----------------------------------------
到目前为止,一切正常,每个表都有唯一的EXT_CODE,因此在请求从外部系统进行更新时,始终只返回一行。当存在ext_code = null的客户端时,无法从外部系统维护它,因为where = null,永远不会返回任何内容。只有一个客户端具有相同的EXT_CODE,但是没有此EXT_CODE的任何数量的客户端(列可以为空)
现在来了困难的部分。 我决定,在此表中,可以存储更多(独立)客户的数据。出于这个原因,我添加了一个名为CUSTOMER_CODE的新列。 此代码将表分成几个独立的空间,而每个客户只能看到她的数据。
为此,引入了oracle vpd(虚拟专用数据库)。
修改后的表可能会跟随
+---------------+---+-----------+-----------+-----------+ |CUSTOMER_CODE |ID |FIRST_NAME |LAST_NAME |EXT_CODE | +---------------+---+-----------+-----------+-----------+ |C1 |1 |Peter |Pletan |ABC | |C1 |2 |John |Dollar |DEF | |C1 |3 |Mia |Zin |GHI | |C1 |4 |Jasper |Blau |NULL | |C1 |5 |George |Khan |NULL | |C2 |6 |Paul |Walker |1 | |C2 |7 |Simon |Sleeper |2 | |C2 |8 |Lian |Driver |3 | |C2 |9 |Cor |Pilot |NULL | |C2 |10 |Martin |Oldman |NULL | ---------------------------------------------------------
这被视为一般概述。当客户C1登录时,她只能看到1-5行,而C2 6-10。
问题出现了
+---------------+---+-----------+-----------+-----------+ |CUSTOMER_CODE |ID |FIRST_NAME |LAST_NAME |EXT_CODE | +---------------+---+-----------+-----------+-----------+ |C1 |1 |Peter |Pletan |ABC | |C2 |2 |John |Dollar |ABC |
我现在的可能性是什么? 1.基于功能的索引(丢弃唯一约束) - 索引,如果any为null,则将两个值都设置为null,因此它根本不会被索引=>可能是一个解决方案,但索引不能与唯一约束相反
触发器 - 检查数据并抛出异常(仅当两个值都不为空时)
使ext_code不为空 - 在组合上放置常规唯一约束(ext_code,customer_code)=>不可行的选择
其他想法 - 我想听听你的意见。
答案 0 :(得分:1)
您还没有说过您使用的是哪个版本的Oracle,但是从11g开始,您可以使用具有唯一约束的虚拟列:
alter table customer add (unq_col varchar2(24) -- or necessary size
generated always as (case when ext_code is null then null
else customer_code||'~'||ext_code end));
alter table customer add (constraint unq_col_con unique (unq_col));
生成的列可以按照您认为安全的方式构建 - 如果您可以识别永远不在其中一个列中的字符,或填充或任何合适的字符,则使用分隔符。
然后尝试复制客户中的代码失败:
update customer set ext_code = 'ABC' where ext_code = 'DEF'
Error report -
SQL Error: ORA-00001: unique constraint (SCHEMA.UNQ_COL_CON) violated
00001. 00000 - "unique constraint (%s.%s) violated"
但是与不同的客户合作是可以的:
update customer set ext_code = 'ABC' where ext_code = '1';
1 row updated.