ORA-01722: invalid number 是 Oracle 開發中頻率最高的數據類型錯誤,核心原因只有一個:**字符串無法隱式轉換為數值**,卻參與了數值運算、比較或插入數值列。
-- Java 異常堆棧
nested exception is java.sql.SQLException: ORA-01722: invalid number
-- 典型觸發 SQL
INSERT INTO account (id, balance) VALUES ('1001', '500.00abc'); -- 字符串含非數字字符
-- 或
SELECT * FROM products WHERE price > '100元'; -- 比較值含非數字
-- 或
UPDATE orders SET amount = '1,000.00' WHERE id = 1; -- 含千分位逗號
TO_NUMBER() 為數值。
// Java PreparedStatement
pstmt.setInt(1, 1001); // 數值類型綁定
pstmt.setBigDecimal(2, new BigDecimal("500.00")); // 精確數值綁定
// 杜絕 setString 插入數值列
-- 移除千分位、貨幣符號
INSERT INTO account (balance) VALUES (TO_NUMBER(REPLACE(REPLACE('1,000.00', ',', ''), '¥', '')));
-- 安全轉換函數 (12c+)
INSERT INTO account (balance) VALUES (TO_NUMBER('500.00abc' DEFAULT NULL ON CONVERSION ERROR));
@Digits/@Pattern 正則。NumberFormatException 返回友好錯誤碼。
-- 列上有索引,但 WHERE 子句用字符串比較
SELECT * FROM large_table WHERE numeric_col = '12345';
-- 執行計劃:INDEX RANGE SCAN → 隱式 TO_NUMBER('12345') → 正常走索引
-- 但若寫反:
SELECT * FROM large_table WHERE '12345' = numeric_col;
-- 執行計劃:FULL TABLE SCAN → 隱式 TO_CHAR(numeric_col) → 索引失效!
鐵律: 比較/連接/插入時,**字面量/參數類型必須與列類型一致**,避免隱式轉換導致索引失效、計劃偏移、ORA-01722。
-- 開啟 SQL Trace 定位具體語句
ALTER SESSION SET SQL_TRACE = TRUE;
-- 或 11g+ 統一審計
AUDIT INSERT, UPDATE, DELETE ON schema.table BY ACCESS WHENEVER NOT SUCCESSFUL;
-- 查看審計紀錄 DBA_AUDIT_TRAIL 定位報錯 SQL
ORA-01722 看似簡單,實則暴露「類型意識薄弱」。從參數綁定、DDL 設計、輸入校驗三層建立強類型防線,才能徹底斬斷這條高發錯誤鏈。