Skip to Main Content
  • Questions
  • ORA-12899: value too large when inserting over DB link with different character sets

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Sreeju.

Asked: November 06, 2017 - 11:56 am UTC

Last updated: November 09, 2021 - 2:51 am UTC

Version: 12.1.0.2.0 - 64bit, 11.2.0.1.0 - 64bit

Viewed 10K+ times! This question is

You Asked

Hi Tom,
We are using two databases with two different character sets those are
11.2.0.1.0 - 64bit = AR8MSWIN1256
12.1.0.2.0 - 64bit = AL32UTF8

Trying to insert a data from the 11.2 version to the 12.1 through a DBLINK but it gives 'ORA-12899: value too large' error for many records, whereas when checking the length of the field gives only 12 characters, but while inserting it says '(actual: 13, maximum: 12)' for the item "OR_ITEMS_TEMP"."ITEMTYPE";

We have tried inserting the data directly Ex:script is given below

-------Create Table--------------
create table or_items_temp (id number, bu varchar2(12), brand varchar2(12), family varchar2(12), catgory varchar2(12), subcatgory varchar2(12),
grp varchar2(12), sgrp varchar2(12), saletype varchar2(12), itmodel varchar2(12), itemtype varchar2(12), uom varchar2(12),
rsp number(15,3), currency varchar2(12), itmobapp varchar2(12), status number(2))
-----End Create Table------------
-------Row details--------------
insert into or_items_temp(id, bu, brand, family, catgory, subcatgory, grp, sgrp, saletype, itmodel, itemtype, uom, rsp, currency, itmobapp,status)
VALUES(1, 'BU80', 'MR LIGHT', 'ELECTRONICS', 'LIGHTING', 'REC. LIGHT', 'COMBO', 'TORCH+TORCH', '01.TRADING', 'MR 670-2 CO', '24+24  EMERG', 'PCS', 104, 'QAR', NULL, 2);
-------End Row details--------------


but when taking the length of the item

select length('24+24  EMERG') from dual; 


it gives 12

We have changed the "OR_ITEMS_TEMP"."ITEMTYPE" length to 14 and inserted the values, it went through successfully. There after we again took the length of the field that too gives the same length as 12.

Why such a behavior? how can we correct this? kindly help

Best Regards,
Sreeju

and Chris said...

This problem is likely due to the fact that characters can be different lengths in bytes in different character sets.

For example, if you compare the byte size of A umlaut in AL32UTF8 and AR8MSWIN1256, you see:

select lengthb(CONVERT('Ä', 'AL32UTF8')) bytes from dual;

BYTES   
      2 

select lengthb(CONVERT('Ä', 'AR8MSWIN1256')) bytes from dual;

BYTES   
      1 


So why's that a problem?

You can declare column lengths using character or byte semantics. This determines whether the length is in bytes or characters. You can't insert a single two-byte character into a 1 byte column:

create table t (
  str_bytes varchar2(1 byte),
  str_chars varchar2(1 char)
);

insert into t values (CONVERT('Ä', 'AL32UTF8'), CONVERT('Ä', 'AL32UTF8'));

ORA-12899: value too large for column "CHRIS"."T"."STR_BYTES" (actual: 2, maximum: 1)

insert into t values (CONVERT('Ä', 'AR8MSWIN1256'), CONVERT('Ä', 'AR8MSWIN1256'));

1 row inserted.

select * from t;

STR_BYTES   STR_CHARS   
?           ? 


So I'm guessing that:

- "OR_ITEMS_TEMP"."ITEMTYPE" was a varchar2(12 byte) on the target
- You have some characters in this column that are a single byte in AR8MSWIN1256, but two in AL32UTF8

You can check the char (C) or byte (B) setting in user_tab_cols:

select column_name, char_used 
from   user_tab_cols
where  table_name = 'T';

COLUMN_NAME   CHAR_USED   
STR_BYTES     B           
STR_CHARS     C 


You can fix this by modifying the length to be in characters instead of bytes:

alter table t modify ( str_bytes varchar2( 1 char ) );

insert into t ( str_bytes ) values (CONVERT('Ä', 'AL32UTF8'));

1 row inserted.

select * from t;

STR_BYTES   STR_CHARS   
?           ?           
�

Rating

  (2 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

You can fix this by modifying the length to be in characters instead of bytes:

A reader, October 28, 2021 - 12:27 pm UTC

I think this does not work in all cases, as the maximum length of varchar2 is 4000 bytes. So even a field with definition varchar2(4000 char) cannot hold 4000 multi byte characters.
Connor McDonald
October 29, 2021 - 5:23 am UTC

Correct. Ultimately you get 4000bytes which will equate to 4000 *or less* characters.

Convert to CLOB

Andrew, November 01, 2021 - 11:17 am UTC

I recommend to my developers, in cases like this, to consider converting the column to CLOB. That will generally solve the problem with few programming changes needed.
Connor McDonald
November 09, 2021 - 2:51 am UTC

glad we could help

More to Explore

Administration

Need more information on Administration? Check out the Administrators guide for the Oracle Database