資料庫中已經存在表。其中包含對列之一的檢查約束。我想在不影響資料庫的情況下更新該約束。
uj5u.com熱心網友回復:
使用alter洗掉并READDcheck約束
Alter table tabname
Drop constraint constraint_name;
Alter table tabname
Add constraint constraint_name check(id<100);
uj5u.com熱心網友回復:
首先洗掉約束,然后添加另一個。
例如:
ALTER table table_name drop constraint constraint_name;
ALTER TABLE table_name
ADD CONSTRAINT constraint_name CHECK (column_name condition );
uj5u.com熱心網友回復:
雖然提供的答案已經足夠了,但我想向您展示當您的表中有大量行時會發生什么,以及您可能擁有的用于要添加的約束的選項。
設想
SQL> create table t1 ( c1 number generated always as identity start with 1 increment by 1 , c2 varchar2(10) ) ;
Table created.
SQL> alter table t1 add constraint chk_c2_val check ( c2 in ( 'AAAAAAAAAA' , 'BBBBBBBBBB' ) );
Table altered.
現在我們將插入大量滿足現有約束的行,讓我們通過使用even和odd值使兩個字串的行數均勻。
SQL> 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.
SQL> select count(*) from t1 ;
COUNT(*)
-----------
10000000
現在讓我們放下約束
SQL> set timing on
SQL> SQL> alter table t1 drop constraint chk_c2_val ;
Table altered.
Elapsed: 00:00:00.04
在這種當前情況下,如果我們知道我們要創建的約束已經滿足現有資料,我們可以從中獲得優勢:
SQL> 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
SQL> 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
如您所見,第二個比第一個慢得多,顯然,因為第一個不檢查任何現有行。不過,它可以用于新的或修改過的行。
ENABLE VALIDATE與 ENABLE 相同。檢查約束并保證對所有行都保持。
ENABLE NOVALIDATE意味著檢查新行或修改行的約束,但現有資料可能會或可能不會違反約束,因為它未經驗證。
概括
If you are sure that the new constraint satisfies the existing data, and you have a huge amount of rows in your table, it is sometimes worth to use ENABLE NOVALIDATE as the constraint will not validate the existing data.
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/338231.html
