SQL 重建約束

轉自yangtingkun

 

文章已同步至我的GAE博客WordPress博客

 

注: 1) ALTER TABLE 表名 ADD CONSTRAINT 新的約束名 約束

2) ALTER TABLE 表名 DROP CONSTRAINT 舊的約束名

3) ALTER TABLE 表名 RENAME 新的約束名 TO 新的約束名 (RENAME不適合SQL Server 2000,2005及以後的沒測試過)

當CHECK約束的條件發生變化時,Oracle沒有辦法直接修改約束的條件,而只能通過刪除約束並重建的方式。

前兩天在讀TOM的Effective Oracle by Design時候,突然意識到以前自己的操作是有問題的。

SQL> CREATE TABLE T
2 (ID NUMBER,
3 NAME VARCHAR2(30),
4 AGE NUMBER CONSTRAINT CK_AGE CHECK (AGE > 16)
5 );

表已創建。

如果需要修改約束CK_AGE的約束條件,已往我的做法如下:

SQL> ALTER TABLE T DROP CONSTRAINT CK_AGE;

表已更改。

SQL> ALTER TABLE T ADD CONSTRAINT CK_AGE1 CHECK(AGE > 18);

表已更改。

但是看TOM的文章的時候,發現TOM是這麼說 的:"我會用兩條命令:一條增加一個新的約束,另一條刪除舊的約束。"開始我還在奇怪,爲什麼TOM先說增加而後說刪除呢。這時我想起TOM在 EXPERT ONE ON ONE ORACLE的EXP那一章似乎介紹過,約束條件完全相同的約束可以重複加在同一張表上。於是,我明白了先增加約束的含義,這樣可以使表中的數據自始至終 都處於約束條件的限制之下,而如果先刪除約束的話,在兩個DDL語句執行之間,對錶執行的DML操作則不會收到約束的限制,雖然這個間隔時間可能很短,但 是不能排除出現這種情況的可能性。

因此正確的操作順序應該是:

SQL> DROP TABLE T;

表已丟棄。

SQL> CREATE TABLE T
2 (ID NUMBER,
3 NAME VARCHAR2(30),
4 AGE NUMBER CONSTRAINT CK_AGE CHECK (AGE > 16)
5 );

表已創建。

SQL> ALTER TABLE T ADD CONSTRAINT CK_AGE1 CHECK(AGE > 18);

表已更改。

SQL> ALTER TABLE T DROP CONSTRAINT CK_AGE;

表已更改。

約束的名稱對應用系統來說沒有實際意義,因此約束名的改變不會造成什麼影響,當然如果追求數據結構和修改前一致,可以通過RENAME CONSTRAINT的方式進行修改。

SQL> ALTER TABLE T RENAME CONSTRAINT CK_AGE1 TO CK_AGE;

表已更改。

採用這種方式,就可以保證表中的數據始終處於約束的限制之下。

大家在讀Oracle的官方文檔或TOM這種大師級的著作時,儘量把每句話的意思都搞清楚,也許只是隨便的一句話,就可以推敲出很多東西,而使你獲益匪淺。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章