The error means that a value exceeds the allowed size for a column. It happens most commonly with VARCHAR2 columns.
Example error:
java.sql.BatchUpdateException: ORA-12899: value too large for column "MY_TABLE"."STRING16" (actual: 322, maximum: 255)
The column STRING16 allows 255 bytes, but the data is 322 bytes long.
Even though the column might be defined as VARCHAR2(255 CHAR), it can still exceed the byte limit due to character encoding!
Before jumping to solutions, let’s check how the column is defined.
1️⃣ Check Your Column Definition
Run the following query to check column details:
SELECT COLUMN_NAME, CHAR_USED, DATA_LENGTH, CHAR_LENGTH FROM DBA_TAB_COLUMNS
WHERE TABLE_NAME = 'MY_TABLE' AND COLUMN_NAME = 'STRING16';
Example output:
COLUMN_NAME CHAR_USED DATA_LENGTH CHAR_LENGTH
--------------------------------------------------
STRING16 C 4000 1024
VARCHAR2(1024 CHAR): The column allows 1024 characters
DATA_LENGTH = 4000: Since Oracle uses UTF-8, each character can take up to 4 bytes
If inserting special characters (e.g., emojis, accented letters), they might exceed 4000 bytes
✅ Solutions to Fix ORA-12899
Solution 1: Ensure Column is Defined in CHAR, Not BYTE
If the column was defined as VARCHAR2(255 BYTE), Oracle restricts it to 255 bytes, not characters.
Fix it by modifying the column to explicitly use characters:
ALTER TABLE MY_TABLE MODIFY STRING16 VARCHAR2(1024 CHAR);
Solution 2: Check Data Size Before Inserting
If inserting large text values, trim them before they exceed 4000 bytes.
Check the byte size of your string:
SELECT LENGTH(your_column), LENGTHB(your_column) FROM MY_TABLE;
LENGTH(): Number of characters
LENGTHB(): Number of bytes
In Java, trim values before inserting:
if (value.getBytes(StandardCharsets.UTF_8).length > 4000) {
value = new String(value.getBytes(StandardCharsets.UTF_8), 0, 4000, StandardCharsets.UTF_8);
}
preparedStatement.setString(1, value);
🔹 This ensures the data never exceeds the column limit.
Solution 3: Trim Trailing Spaces & Special Characters
Hidden spaces or control characters increase byte size without you noticing.
Find and remove hidden characters:
SELECT LENGTHB(your_column), DUMP(your_column, 1016) FROM MY_TABLE;
Trim spaces before inserting:
UPDATE MY_TABLE SET STRING16 = RTRIM(STRING16);
Solution 4: Check Database Character Set
Some databases use UTF-8 (AL32UTF8), where each character may take up to 4 bytes.
Find your database character set:
SELECT parameter, value FROM nls_database_parameters WHERE parameter = 'NLS_CHARACTERSET';
If it’s AL32UTF8, your column needs to be defined in CHAR, not BYTE.
Solution 5: Ensure Java JDBC is Handling Data Correctly
Some JDBC drivers treat setString() incorrectly, leading to unintended truncation or expansion.
Use explicit UTF-8 encoding in Java:
preparedStatement.setString(1, new String(value.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8));
Final Debugging Checklist
✔ Run LENGTHB() to check byte size before inserting
✔ Ensure column uses VARCHAR2(1024 CHAR), not BYTE
✔ Trim long values in Java (.getBytes().length > 4000)
✔ Update your Oracle JDBC driver if using an older version
No comments:
Post a Comment