【完全ガイド】Oracle NUMBER型 vs INTEGER の違い|精度・スケール・BINARY_DOUBLE・PLS_INTEGER 徹底解説
- 作成日 2026.07.24
- Oracle Database
Oracle 開発者なら必ず一度は考える問い:
-- どちらを使うべき?
CREATE TABLE t (
id NUMBER, -- こっち?
count INTEGER -- それとも?
);
驚くべき真実:
INTEGER = NUMBER(38, 0) の完全な別名(シノニム)
内部的に全く同じ。使い分けは慣習と可読性のみの問題です。
しかし、Oracle にはさらに多くの数値型があり、実際は使い分けが重要:
- NUMBER: 汎用、精度・スケール指定可能
- INTEGER: NUMBER(38) の別名
- INT / SMALLINT: これも NUMBER(38) の別名
- NUMERIC / DECIMAL: NUMBER と等価
- FLOAT: NUMBER の別種
- BINARY_FLOAT: 32bit IEEE 754
- BINARY_DOUBLE: 64bit IEEE 754
- PLS_INTEGER: PL/SQL 専用、高速
- SIMPLE_INTEGER: PL/SQL 専用、超高速
さらに、多くの日本語記事が誤解している事実:
SMALLINTは「小さい INTEGER」ではない(NUMBER(38) の別名)DECIMAL(10, 2)は本当に固定小数点ではない(内部は NUMBER)FLOATは BINARY_FLOAT とは別(内部は NUMBER)- BINARY_DOUBLE は金融計算には不適(精度損失)
- PLS_INTEGER は SQL では使えない(PL/SQL 専用)
- PostgreSQL / MySQL の INTEGER とは全く違う
実務では:
- 性能重視: BINARY_DOUBLE を検討
- 金融: NUMBER 一択
- 主キー: NUMBER でも INTEGER でも
- PL/SQL のループカウンタ: PLS_INTEGER
- NULL 不可の高速化: SIMPLE_INTEGER
- 他 DB からの移行: 型マッピング注意
本記事では、Oracle の数値型を完全に理解するための決定版ガイドを、リファレンスとして実用的に整理します。NUMBER と INTEGER の実態、11 種類の数値型の完全比較、選択ガイド、ストレージサイズ、パフォーマンス、他 DB との比較、Rails/Java/Python 対応、実践シナリオ、FAQまで完全網羅。この1本で Oracle 数値型を根本から理解できるようになります。
- 1. 結論:INTEGER は NUMBER(38) の別名
- 2. まず理解する:NUMBER 型の詳細
- 3. Oracle 数値型完全一覧
- 4. FLOAT の実態(罠あり)
- 5. BINARY_FLOAT / BINARY_DOUBLE
- 6. PLS_INTEGER / SIMPLE_INTEGER(PL/SQL 専用)
- 7. 選択ガイド
- 8. ストレージサイズ
- 9. パフォーマンス
- 10. 他 DB との比較
- 11. Rails / Java / Python 対応
- 12. 実践シナリオ
- 13. 予防のベストプラクティス
- 14. トラブルシューティング
- 15. よくある質問(FAQ)
- 15.1. Q1. INTEGER と NUMBER(38) の違いは?
- 15.2. Q2. SMALLINT は本当に小さい?
- 15.3. Q3. どちらを使うべき?
- 15.4. Q4. FLOAT と BINARY_FLOAT は?
- 15.5. Q5. BINARY_DOUBLE は金融で使える?
- 15.6. Q6. PLS_INTEGER を SQL で使いたい
- 15.7. Q7. 主キーの型
- 15.8. Q8. Rails の integer は?
- 15.9. Q9. 他 DB との互換性
- 15.10. Q10. NUMBER のパフォーマンス
- 15.11. Q11. 桁数指定なし NUMBER
- 15.12. Q12. Oracle 23ai の新機能
- 16. 参考リンク
- 17. まとめ
結論:INTEGER は NUMBER(38) の別名
時間がない方向けに、最速の理解を示します。
衝撃の真実
Oracle における数値型の別名関係:
NUMERIC → NUMBER
DECIMAL → NUMBER
INTEGER → NUMBER(38, 0) ← ここ!
INT → NUMBER(38, 0)
SMALLINT → NUMBER(38, 0) ← 実は SMALL じゃない
FLOAT(p) → NUMBER (2進精度指定版)
REAL → FLOAT(63)
DOUBLE PRECISION → FLOAT(126)
INTEGER と NUMBER(38) は完全に同じもの。CREATE TABLE で INTEGER を使っても、内部的には NUMBER(38, 0) として格納されます。
検証
CREATE TABLE test_types (
a NUMBER(38, 0),
b INTEGER,
c INT,
d SMALLINT
);
SELECT column_name, data_type, data_precision, data_scale
FROM user_tab_columns WHERE table_name = 'TEST_TYPES';
結果:
COLUMN_NAME DATA_TYPE DATA_PRECISION DATA_SCALE
A NUMBER 38 0
B NUMBER 0
C NUMBER 0
D NUMBER 0
全て NUMBER に変換されている。
実際に使うべき数値型
| 用途 | 推奨型 |
|---|---|
| 汎用(不明) | NUMBER |
| 整数 | NUMBER(N) or NUMBER |
| 通貨 | NUMBER(12, 2) 等 |
| 主キー | NUMBER(IDENTITY) |
| 科学計算・高速 | BINARY_DOUBLE |
| PL/SQL ループ | PLS_INTEGER |
| PL/SQL NULL 不可 | SIMPLE_INTEGER |
覚えておくべき3つの数値型
NUMBER -- 汎用(金融、DB全般)
BINARY_DOUBLE -- 高速科学計算
PLS_INTEGER -- PL/SQL 内の整数演算
この3つで99%のケースをカバー。
詳細は以下で解説します。
まず理解する:NUMBER 型の詳細
NUMBER(p, s) の意味
NUMBER(precision, scale)
- precision (p): 総桁数(1-38)
- scale (s): 小数点以下桁数(-84 to 127)
例
NUMBER(5, 2) -- 総5桁、小数2桁 → 123.45
NUMBER(10, 0) -- 総10桁、整数のみ
NUMBER(38, 0) -- 最大精度の整数(= INTEGER)
NUMBER -- 制約なし(最大精度 40 桁)
NUMBER(4, -3) -- 千の位まで(1000, 2000, 3000, ...)
内部表現
可変長(1〜22 バイト):
0 → 1 バイト
100 → 2 バイト
100000 → 3 バイト
最大精度 → 22 バイト
格納効率が高い。
NUMBER 型の範囲
-1 × 10^126 から 9.999...9 × 10^125
(最大 38桁の有効数字)
精度と丸め
NUMBER(5, 2)
-- OK
INSERT VALUES (123.45) -- 123.45
INSERT VALUES (123.456) -- 123.46(丸め)
-- エラー
INSERT VALUES (1234.5) -- ORA-01438: value larger than specified precision
Oracle 数値型完全一覧
数値型の別名マッピング
| SQL 型 | 実体 | 説明 |
|---|---|---|
| NUMBER | NUMBER | 汎用 |
| NUMBER(p) | NUMBER(p, 0) | p 桁整数 |
| NUMBER(p, s) | 同左 | p 桁、s 小数 |
| INTEGER | NUMBER(38, 0) | ANSI 標準名 |
| INT | NUMBER(38, 0) | INTEGER 短縮 |
| SMALLINT | NUMBER(38, 0) | 実は SMALL でない |
| NUMERIC | NUMBER | ANSI 標準 |
| NUMERIC(p, s) | NUMBER(p, s) | 同左 |
| DECIMAL | NUMBER | ANSI 標準 |
| DECIMAL(p, s) | NUMBER(p, s) | 同左 |
| FLOAT | NUMBER (2進精度) | ANSI 標準 |
| FLOAT(p) | 2進 p 桁精度 | |
| REAL | FLOAT(63) | ANSI 標準 |
| DOUBLE PRECISION | FLOAT(126) | ANSI 標準 |
| BINARY_FLOAT | 独立型 | 32bit IEEE 754 |
| BINARY_DOUBLE | 独立型 | 64bit IEEE 754 |
PL/SQL 専用型
| 型 | 説明 |
|---|---|
| PLS_INTEGER | 32bit 整数、高速 |
| BINARY_INTEGER | PLS_INTEGER と同じ |
| SIMPLE_INTEGER | PLS_INTEGER + NULL 不可、超高速 |
| SIMPLE_FLOAT | BINARY_FLOAT + NULL 不可 |
| SIMPLE_DOUBLE | BINARY_DOUBLE + NULL 不可 |
| NATURAL | 0 以上の整数 |
| NATURALN | 1 以上の整数 |
| POSITIVE | 1 以上の整数 |
| POSITIVEN | 1 以上 + NOT NULL |
| SIGNTYPE | -1, 0, 1 のみ |
FLOAT の実態(罠あり)
FLOAT は NUMBER の一種
CREATE TABLE t (col FLOAT);
-- ↑ 内部は NUMBER
CREATE TABLE t (col FLOAT(10));
-- ↑ 2進10桁精度の NUMBER
FLOAT vs BINARY_FLOAT
別物です!
| 項目 | FLOAT | BINARY_FLOAT |
|---|---|---|
| 内部 | NUMBER | IEEE 754 |
| 精度 | 正確(10進数) | 近似(2進数) |
| 性能 | 遅い | 高速 |
| サイズ | 可変 | 4 バイト |
| 用途 | 金融 | 科学計算 |
落とし穴
CREATE TABLE t1 (col FLOAT); -- NUMBER の別名
CREATE TABLE t2 (col BINARY_FLOAT); -- IEEE 754
INSERT INTO t1 VALUES (0.1); -- 正確に 0.1
INSERT INTO t2 VALUES (0.1); -- 近似値(0.100000001... 等)
SELECT SUM(col) FROM (SELECT 0.1 col FROM DUAL CONNECT BY LEVEL <= 10);
-- NUMBER: 1.0 完全一致
-- BINARY_FLOAT: 微妙にずれる可能性
BINARY_FLOAT / BINARY_DOUBLE
IEEE 754 準拠
BINARY_FLOAT: 32bit(単精度)
BINARY_DOUBLE: 64bit(倍精度)
特徴
- ハードウェア計算(CPU 直接演算)
- NUMBER より高速
- 近似値(正確な10進数保存不可)
- 特殊値: Inf, -Inf, NaN 対応
使用例
CREATE TABLE scientific_data (
measurement_id NUMBER,
temperature BINARY_DOUBLE, -- 高速演算
pressure BINARY_FLOAT
);
-- 特殊値
INSERT INTO t VALUES ('Inf');
INSERT INTO t VALUES ('-Inf');
INSERT INTO t VALUES ('NaN');
リテラル
SELECT 3.14f FROM DUAL; -- BINARY_FLOAT
SELECT 3.14d FROM DUAL; -- BINARY_DOUBLE
金融には不適
-- 0.1 + 0.2 = ?
SELECT BINARY_DOUBLE '0.1' + BINARY_DOUBLE '0.2' FROM DUAL;
-- 0.30000000000000004 ← 誤差
SELECT NUMBER '0.1' + NUMBER '0.2' FROM DUAL;
-- 0.3 ← 正確
通貨計算には必ず NUMBER。
PLS_INTEGER / SIMPLE_INTEGER(PL/SQL 専用)
PLS_INTEGER
DECLARE
counter PLS_INTEGER := 0;
BEGIN
FOR i IN 1 .. 1000000 LOOP
counter := counter + 1;
END LOOP;
END;
/
特徴:
- 32bit 整数(-2,147,483,648 〜 2,147,483,647)
- ハードウェア演算(PL/SQL の NUMBER より高速)
- PL/SQL 専用(SQL では使えない)
- NULL 許可
SIMPLE_INTEGER
DECLARE
counter SIMPLE_INTEGER := 0; -- 初期値必須
BEGIN
FOR i IN 1 .. 1000000 LOOP
counter := counter + 1;
END LOOP;
END;
/
特徴:
- PLS_INTEGER と同じ範囲
- NULL 不可
- オーバーフロー時ラップアラウンド(例外なし)
- PLS_INTEGER より高速(NULL チェック省略)
- PLSQL_CODE_TYPE=’NATIVE’ で最速
パフォーマンス比較
-- 1000万回ループ
DECLARE
v1 NUMBER := 0;
v2 PLS_INTEGER := 0;
v3 SIMPLE_INTEGER := 0;
BEGIN
-- NUMBER: 遅い
FOR i IN 1..10000000 LOOP v1 := v1 + 1; END LOOP;
-- PLS_INTEGER: 高速
FOR i IN 1..10000000 LOOP v2 := v2 + 1; END LOOP;
-- SIMPLE_INTEGER: 最速
FOR i IN 1..10000000 LOOP v3 := v3 + 1; END LOOP;
END;
/
目安: SIMPLE_INTEGER は NUMBER の 5-10 倍高速。
FOR ループ変数の型
FOR i IN 1..1000000 LOOP ... END LOOP;
-- i は PLS_INTEGER 型(デフォルト)
Oracle が自動最適化。
選択ガイド
フローチャート
どこで使う?
├─ SQL / テーブル
│ ├─ 金融・通貨 → NUMBER(p, s)
│ ├─ 主キー → NUMBER
│ ├─ カウント → NUMBER(N)
│ ├─ 科学計算・大量計算 → BINARY_DOUBLE
│ └─ 汎用 → NUMBER
│
└─ PL/SQL 内変数
├─ ループカウンタ → PLS_INTEGER (自動)
├─ NULL 不可の整数 → SIMPLE_INTEGER
├─ 高速な計算 → BINARY_DOUBLE + SIMPLE_DOUBLE
├─ 金融計算 → NUMBER
└─ 汎用 → PLS_INTEGER or NUMBER
ケース別推奨
金融アプリ:
amount NUMBER(15, 2) -- 通貨額
rate NUMBER(5, 4) -- 利率
在庫管理:
quantity NUMBER(10) -- 数量
weight NUMBER(8, 3) -- 重量
科学データ:
temperature BINARY_DOUBLE
pressure BINARY_DOUBLE
主キー:
id NUMBER GENERATED ALWAYS AS IDENTITY
-- または
id NUMBER(19) -- BIGINT 相当
ストレージサイズ
NUMBER の可変長
NUMBER 型は 1-22 バイトの可変長:
値 バイト数
0 1
1〜99 2
100〜9999 3
NULL 0(別途フラグ)
格納効率が高い、大量データで有利。
固定長型との比較
BINARY_FLOAT: 4 バイト(固定)
BINARY_DOUBLE: 8 バイト(固定)
NUMBER: 1-22 バイト(可変)
実測
SELECT column_name, avg_col_len
FROM user_tab_columns
WHERE table_name = 'MY_TABLE';
-- 実際の平均バイト数
パフォーマンス
NUMBER vs BINARY_DOUBLE
大量計算(例: LOG 集計):
-- 遅い: NUMBER
SELECT SUM(LN(amount)) FROM huge_table;
-- 高速: BINARY_DOUBLE
SELECT SUM(LN(CAST(amount AS BINARY_DOUBLE))) FROM huge_table;
BINARY_DOUBLE のほうが 2-10 倍高速なケース多い。
インデックスの効率
- NUMBER: 可変長のためインデックスは若干サイズ大きい
- BINARY_DOUBLE: 固定長、インデックス効率良い
集計処理
PGA の消費:
- BINARY_DOUBLE: 固定 8 バイト
- NUMBER: 平均 5-10 バイト
大量ソートで PGA 消費差が出る。PGA 関連は ORA-04030: process memory の記事も参照してください。
インデックス比較
-- NUMBER のインデックス
CREATE INDEX idx1 ON t(number_col);
-- BINARY_DOUBLE のインデックス
CREATE INDEX idx2 ON t(bin_double_col);
-- 検索速度差はある程度あるが、
-- 通常は精度優先で NUMBER
他 DB との比較
型マッピング表
| Oracle | PostgreSQL | MySQL | SQL Server |
|---|---|---|---|
| NUMBER | NUMERIC | DECIMAL | DECIMAL |
| INTEGER | INTEGER | INT | INT |
| NUMBER(19, 0) | BIGINT | BIGINT | BIGINT |
| NUMBER(10, 0) | INTEGER | INT | INT |
| NUMBER(5, 0) | SMALLINT | SMALLINT | SMALLINT |
| BINARY_FLOAT | REAL | FLOAT | REAL |
| BINARY_DOUBLE | DOUBLE PRECISION | DOUBLE | FLOAT |
重要な違い
PostgreSQL/MySQL の INTEGER:
- 32bit 整数 (-2^31 to 2^31-1)
- 4 バイト固定
- 高速
Oracle の INTEGER:
- NUMBER(38, 0)(最大精度)
- 可変長
- PostgreSQL/MySQL の INTEGER より大きな数を扱える
移行時の注意:
PostgreSQL: id INTEGER (4 バイト)
↓ 移行
Oracle: id NUMBER(10) (可変長、より広い範囲)
Rails / Java / Python 対応
Rails ActiveRecord
Rails のマイグレーション:
class CreateUsers < ActiveRecord::Migration[8.0]
def change
create_table :users do |t|
t.bigint :login_count # NUMBER(19)
t.integer :age # NUMBER(10)
t.decimal :balance, precision: 12, scale: 2 # NUMBER(12, 2)
t.float :score # BINARY_FLOAT
end
end
end
oracle_enhanced adapter の変換:
bigint→ NUMBER(19)integer→ NUMBER(10)decimal→ NUMBER(p, s)float→ NUMBER(BINARY_FLOAT ではない)
Rails 8 系の詳細は Rails 8 アップグレードガイドの記事、rails db:migrate 使い方の記事、find/find_by/where の記事も参照してください。
Java
// JDBC 型マッピング
NUMBER → java.math.BigDecimal
NUMBER(10, 0) → int, long, BigDecimal
NUMBER(19, 0) → long, BigDecimal
BINARY_FLOAT → float
BINARY_DOUBLE → double
// 明示的キャスト
BigDecimal balance = rs.getBigDecimal("balance");
double score = rs.getDouble("score");
Python (oracledb)
import oracledb
# 型マッピング
NUMBER → int or float (適切に判定)
BINARY_FLOAT → float
BINARY_DOUBLE → float
# Decimal 使用
import decimal
oracledb.defaults.fetch_decimals = True
# 全ての数値を Decimal で取得
実践シナリオ
シナリオ1:新規テーブル設計
CREATE TABLE orders (
order_id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
customer_id NUMBER(10) NOT NULL,
order_date DATE NOT NULL,
amount NUMBER(15, 2) NOT NULL, -- 通貨は NUMBER
quantity NUMBER(10) NOT NULL,
discount_rate NUMBER(3, 2), -- 0.00-9.99
weight BINARY_DOUBLE, -- 科学測定値
temperature BINARY_DOUBLE
);
シナリオ2:金融計算(NUMBER 必須)
-- ❌ BINARY_DOUBLE は誤差
CREATE TABLE bad_finance (
amount BINARY_DOUBLE -- ← ダメ!
);
-- ✅ NUMBER で正確に
CREATE TABLE good_finance (
amount NUMBER(15, 2) -- 円: 15桁整数、小数2桁
);
-- 消費税計算
SELECT amount,
ROUND(amount * 0.10, 0) AS tax,
amount + ROUND(amount * 0.10, 0) AS total
FROM orders;
シナリオ3:高速集計(BINARY_DOUBLE)
-- 大量データの科学計算
SELECT SUM(LN(CAST(measurement AS BINARY_DOUBLE))) AS log_sum
FROM huge_scientific_data;
シナリオ4:PL/SQL バッチ処理
DECLARE
counter PLS_INTEGER := 0;
batch_size PLS_INTEGER := 1000;
processed SIMPLE_INTEGER := 0;
BEGIN
FOR rec IN (SELECT * FROM orders WHERE status = 'PENDING') LOOP
counter := counter + 1;
processed := processed + 1;
-- 処理
process_order(rec.order_id);
IF counter = batch_size THEN
COMMIT;
counter := 0;
END IF;
END LOOP;
COMMIT;
END;
/
分析関数は Oracle 分析関数(OVER/PARTITION BY)の記事、Solid Queue の詳細は Solid Queue 使い方の記事も参照してください。
シナリオ5:PIVOT との組み合わせ
-- 月次売上(NUMBER)でクロス集計
SELECT * FROM (
SELECT customer_id, TO_CHAR(order_date, 'MM') month, amount
FROM orders
)
PIVOT (
SUM(amount) -- NUMBER 集計
FOR month IN ('01' AS jan, '02' AS feb, '03' AS mar)
);
PIVOT の詳細は Oracle PIVOT/UNPIVOT の記事を参照してください。
シナリオ6:他 DB からの移行
-- PostgreSQL からの移行
-- PostgreSQL: id BIGINT PRIMARY KEY
-- Oracle: id NUMBER(19) PRIMARY KEY
-- PostgreSQL: price NUMERIC(10, 2)
-- Oracle: price NUMBER(10, 2)
-- PostgreSQL: score REAL
-- Oracle: score BINARY_FLOAT -- または NUMBER
シナリオ7:Data Pump インポート
# インポート時の型マッピング確認
impdp system/pw dumpfile=data.dmp tables=orders
# 元 DB の型が Oracle にどうマップされたか
Data Pump の詳細は Oracle Data Pump 使い方の記事も参照してください。
シナリオ8:Docker Oracle での検証
docker exec -it oracle-xe sqlplus scott/tiger <<EOF
CREATE TABLE type_test (
a NUMBER, b INTEGER, c INT, d SMALLINT,
e NUMERIC, f DECIMAL, g BINARY_FLOAT, h BINARY_DOUBLE
);
SELECT column_name, data_type, data_precision, data_scale
FROM user_tab_columns WHERE table_name = 'TYPE_TEST';
EOF
Docker 関連は docker daemon 接続エラーの記事、Docker no space left on device の記事も参照してください。
シナリオ9:Rails アプリでの数値型
# app/models/order.rb
class Order < ApplicationRecord
# amount: NUMBER(15, 2) → BigDecimal
# quantity: NUMBER(10) → Integer
# score: NUMBER(3, 2) → BigDecimal
validates :amount, presence: true, numericality: { greater_than: 0 }
# 精度重要な計算は BigDecimal
def total_with_tax
amount * BigDecimal("1.10")
end
end
シナリオ10:レガシー DB のリファクタリング
-- 昔の設計(誤解)
CREATE TABLE legacy (
small_num SMALLINT -- 小さい整数のつもり
);
-- 実は NUMBER(38, 0)、無駄
-- リファクタリング:
ALTER TABLE legacy MODIFY small_num NUMBER(5);
-- 小さい範囲を明示、若干のストレージ削減
予防のベストプラクティス
1. 用途を明示的に
-- ❌ 曖昧
CREATE TABLE t (val NUMBER);
-- ✅ 意図明確
CREATE TABLE t (
price NUMBER(10, 2), -- 通貨
count NUMBER(10), -- カウント
ratio NUMBER(3, 2) -- 0-9.99
);
2. 金融は必ず NUMBER
-- 通貨は BINARY_* を使わない
amount NUMBER(15, 2)
3. 大量計算では BINARY_DOUBLE
-- 科学計算・統計
SELECT SUM(x * y) FROM data
-- x, y が BINARY_DOUBLE ならより高速
4. PL/SQL では PLS_INTEGER
FOR i IN 1..N LOOP -- 自動 PLS_INTEGER
counter PLS_INTEGER := 0; -- 明示
5. NULL 不可なら SIMPLE_INTEGER
counter SIMPLE_INTEGER := 0; -- 初期値必須
6. 型変換のオーバーヘッド
-- 頻繁な CAST は避ける
CAST(number_col AS BINARY_DOUBLE) -- コストあり
7. インデックス設計
-- 主キーは NUMBER が標準
CREATE TABLE t (
id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY
);
8. 他 DB 連携の考慮
移行時の型マッピングを文書化
9. Rails でのマイグレーション
# 明示的な型指定
t.decimal :price, precision: 10, scale: 2
10. 一貫性
プロジェクト内で NUMBER/INTEGER 等の使い分けを統一
トラブルシューティング
ORA-01438: value larger than specified precision
-- NUMBER(5, 2) に 1000 を入れると発生
INSERT VALUES (1234.5); -- ORA-01438
対処: 精度を増やす or 入力チェック。
予期しない丸め
INSERT INTO t VALUES (0.005);
-- NUMBER(4, 2) だと 0.01 に丸め
丸め動作: 半分は偶数側(銀行家丸め)ではない。通常の四捨五入。
BINARY_DOUBLE の精度損失
SELECT BINARY_DOUBLE '0.1' + BINARY_DOUBLE '0.2' FROM DUAL;
-- 0.30000000000000004
対処: 金融は NUMBER、科学は BINARY_DOUBLE。
CAST エラー
CAST('abc' AS NUMBER);
-- ORA-01722: invalid number
数値変換エラーは ORA-01858: non-numeric character の記事も参考にしてください。
他 DB からのインポート精度損失
MySQL INT(11) → Oracle NUMBER(38)
(Oracle は NUMBER(11) にすべき)
明示的な型マッピングを。
PL/SQL の PLS_INTEGER オーバーフロー
DECLARE v PLS_INTEGER;
BEGIN
v := 2147483647 + 1;
-- ORA-01426: numeric overflow
END;
/
対処: NUMBER に変更 or SIMPLE_INTEGER でラップ。
よくある質問(FAQ)
Q1. INTEGER と NUMBER(38) の違いは?
ありません(完全な別名)。
Q2. SMALLINT は本当に小さい?
いいえ。NUMBER(38, 0) の別名。他 DB の SMALLINT とは違う。
Q3. どちらを使うべき?
慣習で選択:
- ANSI 標準準拠: INTEGER
- Oracle 標準: NUMBER
- どちらでも同じ
Q4. FLOAT と BINARY_FLOAT は?
別物:
- FLOAT: NUMBER の一種(正確)
- BINARY_FLOAT: IEEE 754(近似)
Q5. BINARY_DOUBLE は金融で使える?
NO。0.1 + 0.2 = 0.30000…4 のような誤差。
Q6. PLS_INTEGER を SQL で使いたい
不可。PL/SQL 専用。SQL では NUMBER。
Q7. 主キーの型
NUMBER 一択(IDENTITY 列で)。
Q8. Rails の integer は?
NUMBER(10)、bigint は NUMBER(19)。
Q9. 他 DB との互換性
ANSI 標準名(INTEGER, DECIMAL) を使うと移植しやすい。
Q10. NUMBER のパフォーマンス
通常十分。大量計算のみ BINARY_DOUBLE 検討。
Q11. 桁数指定なし NUMBER
NUMBER = 最大精度(40 桁)。推奨されない、明示的指定推奨。
Q12. Oracle 23ai の新機能
JSON 型内の数値は BINARY_DOUBLE 相当。
参考リンク
Oracle 公式
- Oracle Database SQL Language Reference: Data Types
- Oracle Database Concepts: Numeric Data Types
- PL/SQL Language Reference: PL/SQL Data Types
まとめ
Oracle 数値型の要点を再整理します。
衝撃の真実
INTEGER = NUMBER(38, 0) ← 完全な別名
INT = NUMBER(38, 0)
SMALLINT = NUMBER(38, 0) ← 実は SMALL でない
NUMERIC = NUMBER
DECIMAL = NUMBER
実際に使うべき型
覚えるべき3つ:
NUMBER -- 汎用(金融、DB全般)
BINARY_DOUBLE -- 高速科学計算
PLS_INTEGER -- PL/SQL 内の整数演算
選択ガイド
| 用途 | 推奨型 |
|---|---|
| 通貨・金融 | NUMBER(p, s) |
| 主キー | NUMBER (IDENTITY) |
| カウント | NUMBER(N) |
| 科学計算・高速 | BINARY_DOUBLE |
| PL/SQL ループ | PLS_INTEGER |
| PL/SQL NULL不可 | SIMPLE_INTEGER |
全数値型リファレンス
SQL 型:
- NUMBER, NUMBER(p), NUMBER(p, s)
- INTEGER, INT, SMALLINT = NUMBER(38, 0)
- NUMERIC, DECIMAL = NUMBER
- FLOAT, REAL, DOUBLE PRECISION = NUMBER 系
- BINARY_FLOAT (32bit IEEE 754)
- BINARY_DOUBLE (64bit IEEE 754)
PL/SQL 型:
- PLS_INTEGER (32bit, 高速)
- SIMPLE_INTEGER (NULL 不可, 超高速)
- SIMPLE_FLOAT / SIMPLE_DOUBLE
- NATURAL, POSITIVE 等
パフォーマンス
金融: NUMBER 一択(BINARY_* は誤差)
科学: BINARY_DOUBLE で 2-10 倍高速
PL/SQL: PLS_INTEGER で 5-10 倍高速
他 DB との違い
Oracle INTEGER (NUMBER(38))
≠ PostgreSQL INTEGER (32bit)
≠ MySQL INT (32bit)
移行時に注意。
予防のベストプラクティス
- 用途を明示的に(NUMBER(15, 2) 等)
- 金融は必ず NUMBER
- 大量計算では BINARY_DOUBLE
- PL/SQL では PLS_INTEGER
- NULL 不可なら SIMPLE_INTEGER
- 型変換のオーバーヘッド意識
- 他 DB 連携の考慮
- プロジェクト内で統一
事故防止
- INTEGER と NUMBER(38) は同じ(別名を選ぶ理由がない)
- SMALLINT は「小さい」ではない
- BINARY_ は金融で使わない*
- FLOAT ≠ BINARY_FLOAT
- PL/SQL 変数は PLS_INTEGER 推奨
これらの知識は、Oracle でのデータベース設計・スキーマ設計・アプリ開発・他 DB からの移行・パフォーマンスチューニング・金融アプリ・科学計算アプリ・Rails / Java / Python 開発など、あらゆる場面で活用できます。本記事をブックマークしておけば、Oracle 数値型を確実に理解・選択できるようになります。
本記事は2026年6月時点の情報をもとに、Oracle Database 19c〜23ai での動作確認・公式ドキュメントに基づき作成しています。Oracle のバージョンにより挙動が異なる場合があるため、最新の情報は Oracle 公式ドキュメント(docs.oracle.com)もあわせてご確認ください。
-
前の記事
【完全ガイド】Oracle PIVOT / UNPIVOT 徹底解説|クロス集計・動的PIVOT・実践パターンまで 2026.07.24
-
次の記事
【完全ガイド】Oracle 分析関数 (OVER/PARTITION BY) 徹底解説|LEAD・LAG・累計・移動平均・ランキングまで 2026.07.26
コメントを書く