『Oracle管理者ガイド』では、次のように述べられています。
ALTER TABLE ... MODIFYステートメントを使用して、既存の列定義を変更します。列のデータ型、デフォルト値、列の制約、列式(仮想列の場合)、および列の暗号化を変更できます。
既存のすべてのデータが新しい長さを満たす場合は、既存の列の長さを増やしたり、減らしたりできます。列をバイトセマンティクスからCHARセマンティクスに、またはその逆に変更できます。空でないCHAR列の長さを短くするには、初期化パラメータBLANK_TRIMMING = TRUEを設定する必要があります。
データ型CHARの列の長さを増やすためにテーブルを変更する場合、これは時間がかかる操作であり、特にテーブルに多くの行が含まれている場合は、かなりの追加ストレージが必要になる可能性があることに注意してください。これは、新しい列の長さを満たすために、各行のCHAR値に空白を埋め込む必要があるためです。
『Oracle SQL言語リファレンス』には、次のような詳細が含まれています。
列のすべての行にnullが含まれている場合は、列のデータ型を変更できます。ただし、マテリアライズド・ビューのコンテナ表の列のデータ型を変更すると、対応するマテリアライズド・ビューが無効になります。
すべての行にnullが含まれているかどうかに関係なく、文字列またはraw列のサイズまたは数値列の精度をいつでも増やすことができます。データを変更する必要がない限り、列のデータ型のサイズを小さくできます。データベースは既存のデータをスキャンし、新しい長さ制限を超えるデータが存在する場合はエラーを返します。
DATE列をTIMESTAMPまたはTIMESTAMP WITH LOCAL TIME ZONEに変更できます。TIMESTAMP WITH LOCAL TIME ZONEをDATE列に変更できます。
テーブルが空の場合、日時列または時間隔列の先行フィールドまたは小数秒の値を増減できます。テーブルが空でない場合は、日時列または間隔列の先行フィールドまたは小数秒のみを増やすことができます。
CHARおよびVARCHAR2列の場合、長さセマンティクスを変更するには、CHAR(最初はバイトで指定された列の文字セマンティクスを示す)またはBYTE(最初は文字で指定された列のバイトセマンティクスを示す)を指定します。既存の列の長さセマンティクスを確認するには、ALL_、USER_、またはDBA_TAB_COLUMNSデータディクショナリビューのCHAR_USED列をクエリします。
上記のドキュメントには追加情報と制限があります。以下は、Number列の精度を下げ、Varchar2の長さを短くしようとする試みのデモです。他の変更を試して、何が起こるかを知ることができます。
--Setup.
DROP TABLE FOO;
CREATE TABLE FOO (BAR Number, BAR2 VARCHAR2(300));
INSERT INTO FOO (SELECT Level, RPAD(to_char(Level),10*Level,to_char(Level))
FROM DUAL CONNECT BY Level <=20);
COMMIT;
SELECT * FROM FOO;
--Reduce Number to Number(10).
ALTER TABLE FOO MODIFY (BAR NUMBER (10));
--Reduce Varchar2(300) to Varchar2(100) (data would be truncated).
ALTER TABLE FOO MODIFY (BAR2 VARCHAR2(100));
--Reduce Varchar2(300) to Varchar2(200) (no data would be truncated).
ALTER TABLE FOO MODIFY (BAR2 VARCHAR2(200));
alterステートメントの出力は次のとおりです。
ALTER TABLE FOO MODIFY (BAR NUMBER (10))
Error report:
SQL Error: ORA-01440: column to be modified must be empty to decrease precision or scale
01440. 00000 - "column to be modified must be empty to decrease precision or scale"
ALTER TABLE FOO MODIFY (BAR2 VARCHAR2(100))
Error report:
SQL Error: ORA-01441: cannot decrease column length because some value is too big
01441. 00000 - "cannot decrease column length because some value is too big"
table FOO altered.
新しい列を作成して精度を下げます。
ALTER TABLE FOO ADD (BAR3 NUMBER(10));
UPDATE FOO SET Bar3 = Bar;
ALTER TABLE FOO DROP COLUMN BAR;
ALTER TABLE FOO RENAME COLUMN BAR3 TO BAR;