#sql #oracle
Вопрос:
В базе данных уже есть существующая таблица. Которые содержат контрольное ограничение для одного из столбцов. Я хочу обновить это ограничение, не затрагивая базу данных.
Комментарии:
1. Вам нужно, чтобы новое ограничение применялось к существующим строкам?
2. @Уильям Робертсон, именно в этом смысл моего ответа.
Ответ №1:
Используйте alter
отказаться и readd check
ограничений
Alter table tabname Drop constraint constraint_name; Alter table tabname Add constraint constraint_name check(idlt;100);
Ответ №2:
Сначала отбросьте ограничение, а затем добавьте другое.
Например:
ALTER table table_name drop constraint constraint_name; ALTER TABLE table_name ADD CONSTRAINT constraint_name CHECK (column_name condition );
Ответ №3:
Хотя предоставленных ответов достаточно, я хотел показать вам , что происходит, когда в вашей таблице очень большое количество строк, и какие у вас могут быть варианты для ограничения, которое вы хотите добавить.
Сценарий
SQLgt; create table t1 ( c1 number generated always as identity start with 1 increment by 1 , c2 varchar2(10) ) ; Table created. SQLgt; alter table t1 add constraint chk_c2_val check ( c2 in ( 'AAAAAAAAAA' , 'BBBBBBBBBB' ) ); Table altered.
Теперь мы вставим огромное количество строк, удовлетворяющих существующему ограничению, давайте сравним количество строк с двумя строками, используя even
odd
значения и.
SQLgt; declare 2 begin 3 for i in 1 .. 10000000 4 loop 5 insert into t1 ( c2 ) values ( case when mod(i,2)=0 then 'AAAAAAAAAA' else 'BBBBBBBBBB' end ); 6 end loop; 7 commit; 8 end; 9 / PL/SQL procedure successfully completed. SQLgt; select count(*) from t1 ; COUNT(*) ----------- 10000000
Теперь давайте отбросим это ограничение
SQLgt; set timing on SQLgt; SQLgt; alter table t1 drop constraint chk_c2_val ; Table altered. Elapsed: 00:00:00.04
Находясь в этой текущей ситуации, если мы знаем, что ограничение, которое мы собираемся создать, удовлетворяет уже существующим данным, мы могли бы извлечь из этого выгоду:
SQLgt; alter table t1 add constraint chk_c2_val_1 check ( c2 like 'AAAAAAA%' or c2 like 'BBBBBB%' ) enable novalidate ; Table altered. Elapsed: 00:00:00.03 SQLgt; alter table t1 add constraint chk_c2_val_2 check ( c2 like 'A%' or c2 like 'B%' ) enable validate ; Table altered. Elapsed: 00:00:04.68
Как вы можете видеть, второй, очевидно, намного медленнее первого, так как первый не проверяет ни одну из существующих строк. Однако это подойдет для новых или измененных строк.
ВКЛЮЧИТЬ ПРОВЕРКУ — это то же самое, что ВКЛЮЧИТЬ. Ограничение проверяется и гарантированно сохраняется для всех строк.
ВКЛЮЧИТЬ NOVALIDATE означает, что ограничение проверяется на наличие новых или измененных строк, но существующие данные могут нарушать или не нарушать ограничение, поскольку оно не проверяется.
Краткие сведения
Если вы уверены, что новое ограничение удовлетворяет существующим данным, и у вас в таблице огромное количество строк, иногда его стоит использовать ENABLE NOVALIDATE
, так как ограничение не будет проверять существующие данные.