我希望能够做到以下几点:
insert into myTable values ('myParamName', NULL, 'alskdjflas');
insert into myTable values ('myParamName', 'A', 'asdf');
但当我在之后运行时,它需要给出一个错误
insert into myTable values ('myParamName', 'A', 'asdf2');
我还需要能够做到这一点:
select *
from parameters p
left join myTable mt on mt.parameter_id = p.parameter_id
and mt.visible_mask_substring = NULL
这个:
select *
from parameters p
left join myTable mt on mt.parameter_id = p.parameter_id
and mt.visible_mask_substring = 'A'
因此,我需要能够在第二列上LEFT JOIN
,但如果不将第二列设为主键,就无法做到这一点,但它不能成为主键,因为主键不能为null,但我的数据需要有一个可选的null第二列。
我离放弃和插入单词";NULL";在引号中,这样我就可以让第二列是PK,但允许它为空(可能不是一个合适的解决方案(:
DROP TABLE myTable;
CREATE TABLE myTable
(
parameter_id varchar2(40),
visible_mask_substring varchar2(1),
someVal varchar2(50),
PRIMARY KEY (parameter_id, visible_mask_substring),
CONSTRAINT idek_ibfk_1
FOREIGN KEY (parameter_id) REFERENCES parameters (parameter_id)
);
insert into myTable values ('myParamName', 'NULL', 'alskdjflas');
insert into myTable values ('myParamName', 'A', 'asdf');
parameter_id
和visible_mask_substring
上有一个唯一的键。但与SQL中常见的情况不同,您希望将visible_mask_substring
中的NULL视为另一个特定值。
由于visible_mask_substring
可以包含任何可能的字符串,因此从技术上讲,不可能仅在这两列上具有唯一索引并将NULL作为附加值。
有两种解决方案,都使用函数索引:
如果您知道一个永远不会被使用的值,那么就用它来表示NULL。例如字符串"###NULL###"。该指数看起来像
create index idx on mytable
(
parameter_id,
nvl(visible_mask_substring, '###NULL###')
);
如果您不能保证任何值永远不会被使用(或者如果您只是想要一个清晰的通用解决方案(,请使用三列:
create unique index idx on mytable
(
parameter_id,
nvl(visible_mask_substring, 'NULL'),
decode(visible_mask_substring, null, 'NULL', 'NOTNULL')
);
演示:https://dbfiddle.uk/8HwR8Hox