聯機重定義修改欄位型別(NVARCHAR2->VARCHAR2)
SQL類似如下:
SELECT * FROM T1,T2 WHERE T1.NAME=T2.NAME AND T1.NAME='XXX';
其中T1的NAME型別為:NVARCHAR2
T2的NAME型別為:VARCHAR2[@more@]
這個SQL會發生隱式轉換(VARCHAR2 -> NVARCHAR2),所以,實際執行的SQL是:
SELECT * FROM T1,T2 WHERE T1.NAME=SYS_OP_C2C(T2.NAME) AND T1.NAME=U'XXX';
T2.NAME上多了一個函式,所以不能用到這列上的索引。
這個SQL,應該讓T1和T2都走索引,其實解決方法有兩種:
1、修改SQL
修改方法1:SELECT * FROM T1,T2 WHERE T1.NAME='XXX' AND T2.NAME='XXX';
修改方法2:SELECT * FROM T1,T2 WHERE T1.NAME='XXX' AND TO_CHAR(T1.NAME)=T2.NAME;
由於程式碼修改量大,且很難確保所有SQL都被修改,並且NVARCHAR2佔用的空間多,所以最好的辦法是修改表結構。
2、修改表結構
修改表結構需要聯機修改,否則會影響業務。
在聯機轉換NVARCHAR2到VARCHAR2時,有幾點需要注意:
1)新表的結構VARCHAR2的長度要足夠長,因為NVARCAHR2的長度定義的是字元個數,VARCHAR2定義的是位元組個數。在中文環境下把VARCHAR2的長度定義為NVARCHAR長度的2倍即可。
2)如果主鍵列也需要轉換,則重定義的時候options_flag要用ROWID,不能用主鍵
3)在匹配源表和新表欄位的對應關係時,對源表的列要使用函式轉換
舉一個例子如下:
drop table k1 purge;
drop table k2 purge;
create table k1(a nvarchar2(10) primary key,b nvarchar2(10),c nvarchar2(10));
create table k2(a varchar2(30) primary key,b varchar2(10),c varchar2(10));
insert into k1(a) values('abcsdfsdsa');
insert into k1(a) values('1234567890');
insert into k1(a) values('我是中國人收到測一下');
commit;
exec dbms_redefinition.can_redef_table('suk','k1');
exec DBMS_REDEFINITION.START_REDEF_TABLE('SUK','K1','K2','Translate(a USING CHAR_CS) a,Translate(b USING CHAR_CS) b,Translate(c USING CHAR_CS) c',dbms_redefinition.cons_use_rowid)
exec DBMS_REDEFINITION.SYNC_INTERIM_TABLE('SUK','K1','K2')
exec dbms_redefinition.finish_redef_table('SUK','K1','K2')
--其中TRANSLATE ... USING 函式用於資料庫字符集和國家字符集之間轉換
--dbms_redefinition.cons_use_rowid用於指定轉換主鍵時的 option_flag為rowid
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/231499/viewspace-1013357/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 如何將varchar2修改為clob型別欄位(使用long過渡)型別
- 修改表的欄位型別型別
- sqlite sql 修改欄位型別SQLite型別
- 多型關聯自定義的型別欄位的處理多型型別
- sql語句修改欄位型別和增加欄位SQL型別
- oracle 修改欄位型別的方法Oracle型別
- Oracle 修改欄位型別和長度Oracle型別
- 修改欄位資料型別的方法資料型別
- 關於mysql中欄位定義的型別int、tinyint區別MySql型別
- Sqlserver修改線上表的表欄位型別SQLServer型別
- 物件型介面 / 定製操作型別和欄位物件型別
- Mysql varchar型別欄位為什麼經常定義為255MySql型別
- MySQL-修改欄位型別、設定預設值,以及新增註釋MySql型別
- 【原創】Oracle number date varchar2欄位型別佔用空間大小Oracle型別
- 你或許不知道的varchar2型別的定義型別
- [提問交流]建立模型,新增屬性,欄位型別如何設定2位小數的欄位型別模型型別
- Oracle-不刪表資料,修改欄位型別Oracle型別
- 【轉】修改表的欄位資料型別的方法資料型別
- 保留兩位小數:資料庫欄位型別NUMBER,Java欄位型別Double型別資料庫型別Java
- Oracle varchar2型別欄位插入插入過長資料丟失問題Oracle型別
- 在SQL Server中修改欄位型別和欄位名稱的儲存過程SQLServer型別儲存過程
- oracle分割槽表線上重定義欄位not null問題OracleNull
- MySQL VARCHAR型別欄位到底可以定義多長MySql型別
- MongoDB更改欄位型別MongoDB型別
- oracle的欄位型別Oracle型別
- 6. 自定義容器型別元素驗證,類級別驗證(多欄位聯合驗證)型別
- Oracle 12.2 聯機重定義使用VPD策略的表並修改表的列名Oracle
- 重定義一些基本資料型別資料型別
- MySQL欄位型別最全解析MySql型別
- date、timestamp欄位型別型別
- MySQL欄位型別小記MySql型別
- 資料欄位型別匹配型別
- json Unmarshal時實際欄位型別與struct定義不一致會影響其他正常欄位解析JSON型別Struct
- 物聯網學習教程—用typedef定義型別型別
- 保留資料庫表中的資料,把表中的欄位varchar2改成clob型別資料庫型別
- 【mongo】mongo 欄位型別互轉Go型別
- [轉]MySQL 欄位型別參考MySql型別
- MongoDB中的欄位型別IdMongoDB型別