私のアプリケーションは、テーブルに100万レコードがあるOracleデータベースと対話します。問題は:
そのテーブルには、数値整数型の列があります。浮動小数点値(2桁)を格納します。100を(アプリケーションから)乗算してその列に格納するか、列のデータ型を変更することで、これを行うことができます。質問は:
何がより短い時間で済みますか?表の変更は列またはクエリを変更します(表セットの更新列= 100 * val)。
OracleのANUMBER
には固有の「形式」がありません。つまり、その内部表現はその精度やスケールに依存しません。NUMBER
たとえば、123456は、または:として宣言されている場合、内部的に同じ方法で表されNUMBER(9,2)
ますINTEGER
。
SQL> SELECT dump(CAST(123456 AS INTEGER)) int,
2 dump(CAST(123456 AS NUMBER(9,2))) num
3 FROM dual;
INT NUM
------------------------- --------------------
Typ=2 Len=4: 195,13,35,57 Typ=2 Len=4: 195,13,35,57
INTEGER(7)
anとaの列の唯一の違いは、がより強いチェック制約を持っているNUMBER(9,2)
ことです。INTEGER(7)
両方の列は、まったく同じ方法でデータを内部的に表します。
これが、空でない列の列の精度を問題なく高めることができる理由ですALTER TABLE
。メタデータ(ディクショナリテーブル)のみが変更されるため、やり直しがほとんどなく、すぐに実行できます。
SQL> create table test (id number(7));
Table created.
SQL> insert into test values (123456);
1 row created.
SQL> alter table test modify (id number(9,2));
Table altered.
SQL> select * from test;
ID
----------
123456
既存の列のデータ型を変更することはできません。
ORA-01439:データ型を変更するには、変更する列を空にする必要があります
したがって、float列が必要な場合は、float列を作成し、整数列のデータで更新して、整数列を削除する必要があります。DDLは高速ですが、100万行の更新には時間がかかります。50000行に制限し、更新のたびにコミットすることをお勧めします。こうすることで、より高速になります。
UPDATE MyTable SET NewFloatField = OldINtegerField WHERE NewFloatField IS NULL AND rownum <50000
また、アプリケーションでSQLを変更し、データを挿入するときに100を掛け、データを取得するときに100で割るという別の方法を使用できます。ただし、DBを変更して、データが1つのソースから送信され、挿入または読み取りが行われるすべての場所で解釈される必要がないようにします。