У меня не может быть значения 11. Это должно быть 1-10
. Вы можете использовать проверочное ограничение, чтобы предотвратить добавление значения выше 10; как набросок (например, вам может потребоваться ограничиться целыми числами и использовать более значимые имена ...):
create table a (
id number,
constraint a_pk primary key (id)
);
create table b (
id number,
data varchar2(10),
foreign_id number not null,
unique_id number not null,
constraint b_pk primary key (id),
constraint b_fk foreign key (foreign_id) references a (id),
constraint b_uk unique (foreign_id, unique_id),
constraint b_ch check (unique_id between 1 and 10)
);
insert into a (id) values (101);
insert into a (id) values (102);
Затем вы можете вставить до 10:
insert into b (id, data, foreign_id, unique_id)
select 1, 'SomeData', 101, nvl(max(unique_id), 0) + 1
from b
where foreign_id = 101;
insert into b (id, data, foreign_id, unique_id)
select 2, 'SomeData', 101, nvl(max(unique_id), 0) + 1
from b
where foreign_id = 101;
...
insert into b (id, data, foreign_id, unique_id)
select 10, 'SomeData', 101, nvl(max(unique_id), 0) + 1
from b
where foreign_id = 101;
но попытка вставить 11-е значение не удалась:
insert into b (id, data, foreign_id, unique_id)
select 11, 'SomeData', 101, nvl(max(unique_id), 0) + 1
from b
where foreign_id = 101;
ORA-02290: check constraint (MY_SCHEMA.B_CH) violated
Попытка вставить дубликат также все равно не удалась:
insert into b (id, data, foreign_id, unique_id)
values (11, 'SomeData', 101, 1);
ORA-00001: unique constraint (MYSCHEMA.B_UK) violated
Но у вас есть один и тот же «уникальный» идентификатор для разных внешние ключи:
insert into b (id, data, foreign_id, unique_id)
select 11, 'SomeData', 102, nvl(max(unique_id), 0) + 1
from b
where foreign_id = 102;
select * from b;
ID DATA FOREIGN_ID UNIQUE_ID
---------- ---------- ---------- ----------
1 SomeData 101 1
2 SomeData 101 2
3 SomeData 101 3
4 SomeData 101 4
5 SomeData 101 5
6 SomeData 101 6
7 SomeData 101 7
8 SomeData 101 8
9 SomeData 101 9
10 SomeData 101 10
11 SomeData 102 1
То, как я получаю следующий уникальный идентификатор для каждого внешнего ключа, означает, что если вы удаляете строку, вы не можете повторно использовать ее идентификатор, если только не удаляется тот, который вы удалили. быть самым высоким значением в любом случае. Вы можете сделать вставку более сложной, если вы хотите заполнить пробелы, но вы еще не показали, как вы рассчитываете это, поэтому вы можете не захотеть. Грубый способ, опять же:
delete from b where id = 3;
insert into b (id, data, foreign_id, unique_id)
values (12, 'SomeData', 101,
(
select min(n) from (select level as n from dual connect by level <= 10) x
where not exists (
select null from b where b.foreign_id = 101 and b.unique_id = x.n
)
)
);
Если пробелов нет, скалярный подзапрос получает null
, поэтому вставка завершается неудачно при проверке ненулевого значения.
db < > fiddle
Если вам нужно до 10 значений, но они не могут быть ограничены 1-10, вы можете использовать материализованное представление, чтобы сохранить текущий счет и иметь проверочное ограничение против того, чтобы не превысить 10. Хотя это, кажется, не то, что вы хотите здесь.