国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

實例講解如何更改字段至兼容的不同類型

2024-07-21 02:42:26
字體:
來源:轉載
供稿:網友
在實際的工作和學習中,我們可能由于疏忽將一個字段定義為varchar2類型,后來插入里面的數據又都是數字,在此之后,你會突然發現這個字段確實應該為number類型,而此時如果我們想在不影響用戶使用的前提下,或者說盡量小的影響用戶,保證數據不丟失的情況下,來更改這個數據類型,這個時候如果我們用普通的alter table modify命令,就可能要遇到錯誤了。示例如下:

22:25:31 SQL> select * from t;

A

----------

10

22:25:32 SQL> desc t

名稱 是否為空? 類型

-------------------- --------- --------------------

A VARCHAR2(10)

22:25:34 SQL> alter table t modify(a number);

alter table t modify(a number)

*

第 1 行出現錯誤:

ORA-01439: 要更改數據類型, 則要修改的列必須為空

其實,類似的現象確實很多,如本來應該為date類型,結果被定義成varchar2類型等等,主要就是那些兼容的數據類型之間的轉換定義。當然,為什么一開始會犯這樣的錯誤,那可能原因就有多方面了,如一開始需求就不對等等。

下面,以上面那個例子為基礎,介紹兩種處理這種問題的方法。

第一種方法,通過增加列來完成

22:25:44 SQL> alter table t add (b number);

表已更改。

22:34:16 SQL> update t set b = to_number(a)

已更新 1 行。

22:34:39 SQL> update t set a = null;

已更新 1 行。

22:34:50 SQL> commit;

提交完成。

22:34:52 SQL> select * from t;

A B

---------- ----------

10

22:34:55 SQL> alter table t modify a number

表已更改。

22:35:21 SQL> update t set a=b;

已更新 1 行。

已用時間: 00: 00: 00.01

22:35:33 SQL> commit;

提交完成。

22:35:52 SQL> alter table t drop column b;

表已更改。

在這種方法中最后也可以先drop column a,然后rename column b to a,達到的效果是一樣的。

第二種方法:通過新建表,在新表上更改字段,最后rename新表來完成

22:41:44 SQL> create table t1 as select * from t where 1=2;

表已創建。

22:42:14 SQL> alter table t1 modify (a number);

表已更改。

22:42:24 SQL> insert into t1 select * from t;

已創建 1 行。

22:42:37 SQL> commit;

提交完成。

22:42:40 SQL> drop table t;

表已刪除。

22:42:46 SQL> rename t1 to t;

表已重命名。

22:43:00 SQL> desc t;

名稱 是否為空? 類型

-------------- --------- -------------

A NUMBER

我就知道這兩種常見的方法,不知道還有沒有什么其他的好方法。如果有,請分享。建議使用第一種。

約束和索引都被摧殘了,可以做個實驗證明一下。

先建立測試表并插入數據

15:28:45 SQL> create table t (a varchar2(10) not null);

表已創建。

已用時間: 00: 00: 00.03

15:28:47 SQL> insert into t values ('10');

已創建 1 行。

已用時間: 00: 00: 00.00

15:28:55 SQL> commit;

提交完成。

已用時間: 00: 00: 00.00

然后增加一個列,并且把數據復制過去

15:29:08 SQL> alter table t add (b number);

表已更改。

已用時間: 00: 00: 00.01

15:29:31 SQL> update t set b=to_number(a);

已更新 1 行。

已用時間: 00: 00: 00.01

15:29:42 SQL> commit;

提交完成。

已用時間: 00: 00: 00.00

15:29:45 SQL> alter table t modify b not null;

表已更改。

已用時間: 00: 00: 00.10

在原來的列上建立索引和約束

15:29:59 SQL> create index ind_t_a on t(a);

索引已創建。

已用時間: 00: 00: 00.15

15:31:01 SQL> alter table t add constraint uk_t_a unique(a);

表已更改。

已用時間: 00: 00: 00.03

斗轉星移:

15:31:20 SQL> alter table t drop column a;

表已更改。

已用時間: 00: 00: 01.20

15:32:06 SQL> alter table t rename column b to a;

表已更改。

已用時間: 00: 00: 00.03

查看索引是否還在?可以看到索引已經被損壞了:

15:33:17 SQL> select index_name,status from user_indexes where table_name='T';

未選定行

已用時間: 00: 00: 00.12

15:34:20 SQL> select index_name,status from user_indexes order by 1;

INDEX_NAME STATUS

------------------------------ --------

PK_DEPT VALID

PK_EMP VALID

已用時間: 00: 00: 00.35

然后查看約束是否還在?可以看到它也被摧殘了

15:38:07 SQL> select constraint_name,constraint_type,invalid,table_name from user_constraints where table_name='T';

CONSTRAINT_NAME CONSTRAINT_TYPE INVALID TABLE_NAME

------------------------------ -------------------- ------- -----------

SYS_C005423 C T

已用時間: 00: 00: 00.03

15:38:24 SQL> select constraint_name,constraint_type,invalid,table_name from user_constraints;

CONSTRAINT_NAME CONSTRAINT_TYPE INVALID TABLE_NAME

------------------------------ -------------------- ------- ------------

BIN$lNdA2W97SK69TBAu945o7w==$0 C BIN$W9ZnSgtTS9+Fs/438TqKuA==$0

BIN$6JXde6KdTsum1GYM3py1eg==$0 C BIN$W9ZnSgtTS9+Fs/438TqKuA==$0

SYS_C005423 C T

FK_DEPTNO R EMP

PK_DEPT P DEPT

PK_EMP P EMP

已選擇6行。

已用時間: 00: 00: 00.23

驗證后,唯一約束已經不起作用了

15:38:31 SQL> select * from t;

A

----------

10

已用時間: 00: 00: 00.03

15:39:26 SQL> desc t;

名稱 是否為空? 類型

--------------- --------- ---------------------------

A NOT NULL NUMBER

15:39:29 SQL> insert into t values(10);

已創建 1 行。

已用時間: 00: 00: 00.01

15:39:38 SQL> commit;

提交完成。

已用時間: 00: 00: 00.00

15:39:44 SQL> select * from t;

A

----------

10

10

可能大家會問,為什么還有一個C約束呢?上面的查詢顯示它是not null約束:

15:51:06 SQL> select table_name,constraint_name,column_name from user_cons_columns where table_name='T';

TABLE_NAME CONSTRAINT_NAME COLUMN_NAME

------------------------------ ------------------------------ -----------------

T SYS_C005423 A

16:09:29 SQL> select search_condition from user_constraints where table_name='T';

SEARCH_CONDITION

--------------------------------------------------------------------------------

"A" IS NOT NULL


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 满洲里市| 开平市| 定远县| 城步| 晴隆县| 湘乡市| 盐城市| 屯留县| 吴堡县| 永康市| 南华县| 石景山区| 茌平县| 文山县| 舟曲县| 定西市| 白城市| 瓦房店市| 田东县| 上高县| 紫金县| 临颍县| 龙口市| 龙门县| 崇阳县| 荃湾区| 晋江市| 呼伦贝尔市| 芒康县| 天镇县| 咸宁市| 华蓥市| 南华县| 文昌市| 贡山| 红原县| 余干县| 奎屯市| 东阳市| 宝丰县| 子长县|